From 4db994f800b361905b0b4348d892c5cb87d1f1d4 Mon Sep 17 00:00:00 2001 From: tzhouam Date: Wed, 7 Oct 2026 17:43:03 +0800 Subject: [PATCH 1/5] Repair pinned evidence handoff for knowledge completion --- doc/architecture/SPEC/kb_service.md | 14 +++ .../assemble_depth_campaign.py | 8 +- .../kb_service/foundation_context.py | 77 ++++++++++++++ .../kb_service/init_knowledge.py | 15 ++- .../kb_service/init_knowledge_depth.py | 49 ++++++++- .../kb_service/init_knowledge_inputs.py | 19 +++- .../kb_service/init_knowledge_parallel.py | 12 +-- .../kb_service/init_support.py | 6 +- test/test_kb_depth_assembly.py | 21 ++++ test/test_kb_foundation_completion_context.py | 100 ++++++++++++++++++ test/test_kb_knowledge_depth.py | 48 +++++++++ test/test_kb_model_dispatch.py | 14 +++ 12 files changed, 364 insertions(+), 19 deletions(-) create mode 100644 src/infermatrix_copilot/kb_service/foundation_context.py create mode 100644 test/test_kb_foundation_completion_context.py diff --git a/doc/architecture/SPEC/kb_service.md b/doc/architecture/SPEC/kb_service.md index 94482386..c8282863 100644 --- a/doc/architecture/SPEC/kb_service.md +++ b/doc/architecture/SPEC/kb_service.md @@ -526,6 +526,20 @@ x 必须为正。因阈值停下的调用(`stop_reason="max_budget"`)→ `Mo ## kb init:解释性知识(knowledge) +证据补齐批次可显式设置 `KB_KNOWLEDGE_CONTEXT_VERSION=5`:从已有功能页的固定版本 +引用定位实际实现,优先保留相关测试断言,再读取引用行段及其邻近上下文。已有正文只作 +定位与背景,新说明仍须使用实际展示的源码或项目文档并经过独立评审。默认版本4的提示词 +及历史原生记录保持兼容;更换版本使用新状态目录,保留旧批次修正历史。 + +适配器与 portable 初始化均通过 `SharedModelDispatch` 共享生成和评审槽位,默认总并发13; +`KB_INIT_GLOBAL_CONCURRENCY` 可设置1至13,`KB_INIT_DISPATCH_DIR` 可指定同一主机的共享 +锁目录。基础和深化并行运行时不能各自创建独立槽池。原生输入、流式输出和用量继续保存 +于状态目录的 trace,未报告费用保持未知。 + +深化补齐优先注入目标功能已认可的基础区块,按缺失维度选择完整区块,再加入组件背景。 +保留的深度页须先复核证明和正文哈希;阶段预览及最终组装为这些页面补齐缺少的 owner +导航,避免全部维度已认可的页面因没有新提取而漏掉目录链接。 + `kb init REPO --stage knowledge --dry-run` 在 skeleton 和 modules 之后提炼解释性知识。 `init_knowledge._Knowledge` 从固定源码与相关文档分别生成架构、API、配置、设计取舍、 功能关系和验证六个维度。源码 owner 按最具体的路由边界确定,按改动频率排序;已有 diff --git a/eval/knowledge-depth/assemble_depth_campaign.py b/eval/knowledge-depth/assemble_depth_campaign.py index 5f0dff71..b0c7b95c 100644 --- a/eval/knowledge-depth/assemble_depth_campaign.py +++ b/eval/knowledge-depth/assemble_depth_campaign.py @@ -318,10 +318,12 @@ def assemble(root: Path, state: Path, source: Path, *, retirement_reports=(), "checkpoint_accepted_sha256": accepted_sha, "assembled_sha256": digest(proposed), "baseline_sha256": digest(old) if old is not None else None, "new_facets": added}) # Add only missing depth-page routes; never copy regenerated worker indexes. + # Retained proof-checked baseline pages may intentionally precede their + # navigation publication in a new batch with immutable foundation indexes. indexes, new_links = {}, [] - for page in proposals: - if page in baseline_pages: - continue + routed_pages = {page for page, blocks in old_blocks.items() if blocks} + routed_pages.update(page for page in proposals if DEPTH_BLOCK.search(proposals[page])) + for page in sorted(routed_pages): feature = by_page[page] directory = PurePosixPath(page).parent index = str(directory / "_index.md") diff --git a/src/infermatrix_copilot/kb_service/foundation_context.py b/src/infermatrix_copilot/kb_service/foundation_context.py new file mode 100644 index 00000000..f1b36028 --- /dev/null +++ b/src/infermatrix_copilot/kb_service/foundation_context.py @@ -0,0 +1,77 @@ +"""Pinned knowledge references locate new inputs; they never approve new prose.""" +from __future__ import annotations + +import re + +from ..knowledge_service.lifecycle import Page +from .evidence_bundle import bounded_spans +from .init_support import InitError + + +def context_version(rt): + raw = str(rt.environ.get("KB_KNOWLEDGE_CONTEXT_VERSION", "4")) + if raw not in {"4", "5"}: + raise InitError("KB_KNOWLEDGE_CONTEXT_VERSION must be 4 or 5") + return int(raw) + + +def feature_context(stage, feature, sources, docs, *, source_limit, doc_limit): + """Put fixed-version citations and their implementation context before prefixes. + + Only the shared declared inventory is read. A citation with another pin, + an unreadable file or an invalid range is not evidence. Existing explanations + remain unchanged, and both models still receive the same actual source text. + """ + from .knowledge_depth import depth_page + + index = stage.source_index + if index.identity["pin"] != stage.record.pin: + raise InitError("foundation context index source pin differs") + prefix = re.escape(stage.lifecycle.full_name + "@" + stage.record.pin + ":") + pattern = re.compile(r"^" + prefix + r"(.+):L(\d+)-L(\d+)$") + references = [] + for page in (feature.page, depth_page(feature)): + text = stage.head.get(page, "") + if not text: + continue + for source in Page.parse(text).sources(): + match = pattern.fullmatch(source) + if match: + references.append((match[1], int(match[2]), int(match[3]))) + located, seen = [], set() + for path, start, end in references: + entry = index.entries.get(path) + if not entry or entry.get("status") != "ready" or not 1 <= start <= end <= len(entry["lines"]): + stage.record.unfinished.append(f"feature {feature.id}: existing source locator unavailable: {path}") + continue + lines = entry["lines"] + # Python symbols have actual parsed bodies. Other languages retain + # representative neighboring text, without claiming a runtime relation. + enclosing = [s for s in entry.get("symbols", []) + if s["start"] <= start <= end <= s["end"]] + symbol = min(enclosing, key=lambda s: s["end"] - s["start"], default=None) + left, right = max(1, start - 80), min(len(lines), end + 80) + if symbol and entry.get("language") == "python": + left, right = max(1, symbol["start"] - 2), symbol["end"] + # Put the cited anchor first even when a large enclosing implementation + # cannot fit; a prefix cap must not hide the very location being reused. + for left, right in ((start, end), (left, right)): + key = (path, left, right) + if key in seen: + continue + seen.add(key) + located.append({"path": path, "start": left, "end": right, + "total_lines": len(lines), "language": entry["language"], + "sha256": entry["sha256"], "kind": entry["kind"], + "localization": "existing pinned citation; new claims require independent review", + "text": "\n".join(f"{n}: {lines[n - 1]}" for n in range(left, right + 1))}) + # The caller already reserved related-test bytes. Do not let newly located + # implementation bodies crowd those assertions out of the final packet. + def is_test(item): + return bool(item.get("test_context")) or index.entries.get(item["path"], {}).get("kind") == "test" + tests = [item for item in sources if is_test(item)] + source = bounded_spans(tests + [s for s in located if s["kind"] == "test"] + + [s for s in located if s["kind"] == "source"] + + [item for item in sources if not is_test(item)], source_limit) + documents = bounded_spans([s for s in located if s["kind"] == "doc"] + docs, doc_limit) + return source, documents diff --git a/src/infermatrix_copilot/kb_service/init_knowledge.py b/src/infermatrix_copilot/kb_service/init_knowledge.py index 8d5de7c2..93ef8ce6 100644 --- a/src/infermatrix_copilot/kb_service/init_knowledge.py +++ b/src/infermatrix_copilot/kb_service/init_knowledge.py @@ -121,11 +121,12 @@ def _precheck(self) -> list[str]: return [] def _input_options(self) -> dict: + from .foundation_context import context_version path = self._coverage_policy_path() text = self.overlay.get(path) or self.rt.knowledge.show(self._base_sha, path) or "" options = {"knowledge_policy": hashlib.sha256(text.encode()).hexdigest(), "from_existing": self.from_existing, - "knowledge_prompt_version": 4 if self.rt.unlimited_subscription else 3} + "knowledge_prompt_version": context_version(self.rt) if self.rt.unlimited_subscription else 3} if self.rt.unlimited_subscription: options["foundation_parallel"] = {"version": 1, "workers": parallelism(self.rt), "zcode_start_interval_s": start_interval(self.rt)} @@ -310,7 +311,8 @@ def _build(self, tree: Path) -> InitRecord: "related_owners": [{"owner": o.owner, "scope_prefixes": list(o.prefixes)} for o in self.owners]} if self.rt.unlimited_subscription: - payload["foundation_prompt_version"] = 4 + from .foundation_context import context_version + payload["foundation_prompt_version"] = context_version(self.rt) owner_jobs.append({"owner": owner, "page": page, "payload": payload, "offered": offered, "requested": requested}) continue @@ -400,6 +402,11 @@ def _build(self, tree: Path) -> InitRecord: return self._blocked([f"discovery evidence handoff: {exc}"]) source = bounded_spans([s for s in spans if s["kind"] != "doc"] + source, MAX_SOURCE_BYTES) docs = bounded_spans([s for s in spans if s["kind"] == "doc"] + docs, MAX_DOC_BYTES) + if self.rt.unlimited_subscription: + from .foundation_context import context_version, feature_context + if context_version(self.rt) == 5: + source, docs = feature_context(self, feature, source, docs, + source_limit=MAX_SOURCE_BYTES, doc_limit=MAX_DOC_BYTES) if not source: self.record.unfinished.append(f"feature {feature.id}: missing readable source") continue @@ -411,7 +418,7 @@ def _build(self, tree: Path) -> InitRecord: "existing_knowledge": self._bounded_context({feature.page: self.head.get(feature.page, "")}), "language_sample": self._language_sample()} if self.rt.unlimited_subscription: - payload["foundation_prompt_version"] = 4 + payload["foundation_prompt_version"] = context_version(self.rt) feature_jobs.append({"owner": Owner("feature-" + feature.id, feature.page, ()), "page": feature.page, "payload": payload, "offered": offered, "requested": missing_facets}) @@ -602,7 +609,7 @@ def _section(self, owner: Owner, page: str, data: dict, section: dict, offered: def _judge_evidence(self, entries): payload = getattr(self, "_foundation_payload", {}) - if self.rt.unlimited_subscription and payload.get("foundation_prompt_version") == 4: + if self.rt.unlimited_subscription and payload.get("foundation_prompt_version") in (4, 5): return foundation_evidence(self, payload) return super()._judge_evidence(entries) diff --git a/src/infermatrix_copilot/kb_service/init_knowledge_depth.py b/src/infermatrix_copilot/kb_service/init_knowledge_depth.py index f14e9f34..f156ab63 100644 --- a/src/infermatrix_copilot/kb_service/init_knowledge_depth.py +++ b/src/infermatrix_copilot/kb_service/init_knowledge_depth.py @@ -19,7 +19,7 @@ from .init_budget import BudgetExhausted from .init_coverage import Owner from .init_history import _CheckpointBudget -from .init_knowledge import MAX_DOC_BYTES, _Knowledge +from .init_knowledge import MAX_DOC_BYTES, _Knowledge, _MARKER from .init_stages import _one_line, _page_frontmatter from .init_support import InitError, InitRecord, generate from .knowledge_coverage import audit_coverage, coverage_targets_met, feature_metadata, inventory @@ -182,6 +182,12 @@ def _build(self, tree: Path) -> InitRecord: if problems: return self._blocked(problems + ["refresh stale/edited depth explicitly before extending it"]) self._block_cache[feature.id] = blocks + # A new batch may retain independently approved depth pages + # while its frozen foundation navigation stays unchanged. + # Reconnect those verified pages even when no facet needs a + # fresh extraction; do not rewrite their accepted blocks. + if blocks: + self._link_page(page, _one_line(feature.title) + ":实现深读") initial = audit_depth(self.head, tree, policy, self.record.pin) if initial["problems"]: return self._blocked(initial["problems"]) @@ -500,6 +506,41 @@ def _judge_evidence(self, entries: list[Evidence]) -> list[dict]: "kind": "upstream_text", "text": [f"{n}: {lines[n - 1]}" for n in range(start, end + 1)]}) return out + def _feature_existing_context(self, feature, requested, background): + """Keep this feature's supported foundation before owner background. + + Complete foundation sections are context, never evidence. In particular, + a late validation section must not disappear behind frontmatter, indexes + or another feature in the same component's alphabetic page order. + """ + current = self.head.get(feature.page, "") + markers = list(_MARKER.finditer(current)) + facets = {"flow": "architecture", "dependencies": "features", + "failure_modes": "api"} + wanted = list(dict.fromkeys(facets.get(f, f) for f in requested)) + sections = [] + for number, marker in enumerate(markers): + owner, facet, pin, verdict = marker.groups() + if owner != "feature-" + feature.id or pin != self.record.pin or verdict not in (None, "pass"): + continue + end = markers[number + 1].start() if number + 1 < len(markers) else len(current) + for boundary in ("\n") + validation = marker("validation") + "Actual helper asserts the saved result. [Test](actual-test.py)\n" + current = "Large source metadata.\n" * 300 + marker("architecture") + "Long introduction.\n" * 200 + current += marker("api", "unsure") + "Unsupported API claim.\n" + validation + current += "\n" + "Static inventory.\n" * 500 + stage = object.__new__(_KnowledgeDepth) + stage.head, stage.record = {feature.page: current}, SimpleNamespace(pin=pin) + background = {"repos/demo/components/core/_index.md": "Unrelated navigation.\n" * 500, + "repos/demo/components/core/feature-alpha.md": "Another feature.\n" * 500, + feature.page: current} + context = stage._feature_existing_context(feature, ["validation"], background) + assert next(iter(context)) == feature.page + assert context[feature.page].startswith(validation) + assert "Unsupported API claim" not in context[feature.page] + assert "Static inventory" not in context[feature.page] + assert sum(len(text.encode()) for text in context.values()) <= 4000 + + def test_interrupted_judge_reuses_completed_extraction(world): _baseline(world) gateway = DepthGateway(interrupt=True) diff --git a/test/test_kb_model_dispatch.py b/test/test_kb_model_dispatch.py index 7913caf6..e2ea7d49 100644 --- a/test/test_kb_model_dispatch.py +++ b/test/test_kb_model_dispatch.py @@ -113,6 +113,20 @@ def test_default_host_namespace_shared_across_batch_state_directories(tmp_path): assert SharedModelDispatch(environ={"KB_INIT_DISPATCH_DIR": str(tmp_path / "explicit")}).limit == 13 +def test_adapter_init_batches_share_dispatch_with_portable_batches(tmp_path, monkeypatch): + from infermatrix_copilot.kb_service.init_support import InitRuntime + + monkeypatch.setenv("KB_INIT_DISPATCH_DIR", str(tmp_path / "dispatch")) + monkeypatch.setenv("KB_INIT_GLOBAL_CONCURRENCY", "3") + monkeypatch.setenv("KB_INIT_KNOWLEDGE_CLONE", str(tmp_path / "knowledge")) + monkeypatch.setattr("infermatrix_copilot.kb_service.init_support.ensure_knowledge_clone", lambda _: None) + first = InitRuntime.from_env(SimpleNamespace(), state_dir=tmp_path / "foundation") + second = InitRuntime.from_env(SimpleNamespace(), state_dir=tmp_path / "depth") + portable = SharedModelDispatch() + assert first.gateway._dispatch.directory == second.gateway._dispatch.directory == portable.directory + assert first.gateway._dispatch.limit == second.gateway._dispatch.limit == portable.limit == 3 + + def test_native_gateway_fallbacks_and_judges_use_same_slots_and_keep_recording(tmp_path): active = maximum = 0 mutex = threading.Lock() From bb7cb115e30c61e605320da25044cd2a1606d1c4 Mon Sep 17 00:00:00 2001 From: tzhouam Date: Wed, 7 Oct 2026 17:43:05 +0800 Subject: [PATCH 2/5] Retain audited Jiuwen depth blocks for evidence directed completion --- ...epth-runtime-agent-definition-execution.md | 71 ++++++++++++++++ .../feature-depth-session-input-steering.md | 80 ++++++++++++++++++ .../feature-depth-workspace-git-diff.md | 62 ++++++++++++++ .../feature-depth-a2x-registry-client-sdk.md | 71 ++++++++++++++++ .../feature-depth-command-execution-tool.md | 69 ++++++++++++++++ .../feature-depth-dynamic-memory-cli.md | 71 ++++++++++++++++ .../feature-depth-llm-wiki-knowledge-base.md | 69 ++++++++++++++++ .../feature-depth-pdf-reading-tool.md | 62 ++++++++++++++ .../feature-depth-sdd-design-rail.md | 71 ++++++++++++++++ ...feature-depth-session-messaging-toolkit.md | 80 ++++++++++++++++++ .../feature-depth-user-todos-tool.md | 62 ++++++++++++++ .../feature-depth-video-generation-tools.md | 80 ++++++++++++++++++ .../feature-depth-web-search-tools.md | 71 ++++++++++++++++ .../feature-depth-xiaoyi-alarm-crud.md | 71 ++++++++++++++++ .../feature-depth-xiaoyi-calendar-tools.md | 53 ++++++++++++ .../feature-depth-xiaoyi-call-phone-tool.md | 62 ++++++++++++++ .../feature-depth-xiaoyi-collection-tools.md | 53 ++++++++++++ .../feature-depth-xiaoyi-contact-search.md | 69 ++++++++++++++++ .../feature-depth-xiaoyi-location-tool.md | 51 ++++++++++++ .../feature-depth-xiaoyi-note-tools.md | 51 ++++++++++++ ...eature-depth-xiaoyi-photo-gallery-tools.md | 62 ++++++++++++++ ...-depth-xiaoyi-pushdata-store-and-viewer.md | 53 ++++++++++++ ...eature-depth-xiaoyi-save-to-phone-tools.md | 53 ++++++++++++ ...eature-depth-xiaoyi-timestamp-utc8-tool.md | 71 ++++++++++++++++ ...depth-agent-template-layered-validation.md | 62 ++++++++++++++ .../feature-depth-arxiv-visual-extraction.md | 42 ++++++++++ ...ure-depth-ascend-chrome-trace-generator.md | 51 ++++++++++++ ...re-depth-ascend-trace-analysis-pipeline.md | 82 +++++++++++++++++++ ...depth-ascend-trace-auto-instrumentation.md | 53 ++++++++++++ ...pth-ascend-trace-compile-safety-checker.md | 71 ++++++++++++++++ ...th-ascend-trace-instrumentation-planner.md | 62 ++++++++++++++ ...feature-depth-ascend-trace-preprocessor.md | 73 +++++++++++++++++ ...ture-depth-audit-integrity-hmac-signing.md | 60 ++++++++++++++ ...eature-depth-audit-report-html-renderer.md | 51 ++++++++++++ ...epth-cross-channel-history-search-skill.md | 62 ++++++++++++++ .../feature-depth-daily-report-skill.md | 71 ++++++++++++++++ ...ture-depth-deepsearch-research-pipeline.md | 82 +++++++++++++++++++ .../feature-depth-docx-pro-cli.md | 64 +++++++++++++++ ...feature-depth-financial-document-parser.md | 71 ++++++++++++++++ ...ture-depth-github-issue-feedback-script.md | 71 ++++++++++++++++ ...ature-depth-huawei-maas-apikey-creation.md | 62 ++++++++++++++ ...feature-depth-huawei-maas-cdp-authorize.md | 71 ++++++++++++++++ ...ure-depth-huawei-realname-account-check.md | 73 +++++++++++++++++ .../feature-depth-local-doc-ocr-offline.md | 62 ++++++++++++++ .../feature-depth-maas-auto-open-models.md | 62 ++++++++++++++ .../feature-depth-opc-add-slide.md | 62 ++++++++++++++ .../feature-depth-opc-pack-validate.md | 82 +++++++++++++++++++ ...eature-depth-plugin-package-initializer.md | 53 ++++++++++++ ...-depth-plugin-package-layered-validator.md | 82 +++++++++++++++++++ .../feature-depth-ppt-deck-finalize.md | 71 ++++++++++++++++ .../feature-depth-ppt-evidence-preparation.md | 60 ++++++++++++++ ...ture-depth-ppt-execution-lock-validator.md | 60 ++++++++++++++ .../feature-depth-ppt-figure-panel-layout.md | 53 ++++++++++++ .../feature-depth-ppt-opc-thumbnail.md | 62 ++++++++++++++ ...ature-depth-ppt-system-diagram-renderer.md | 60 ++++++++++++++ .../feature-depth-pptx-structural-audit.md | 62 ++++++++++++++ .../feature-depth-rsi-dataset-folder-check.md | 73 +++++++++++++++++ .../feature-depth-skill-generator-cli.md | 53 ++++++++++++ .../feature-depth-skill-page-scrape-blocks.md | 71 ++++++++++++++++ .../feature-depth-sop-structure-extraction.md | 44 ++++++++++ ...epth-video-coarse-scan-frame-extraction.md | 73 +++++++++++++++++ .../feature-depth-xlsx-add-computed-column.md | 71 ++++++++++++++++ .../feature-depth-xlsx-doctor-selfcheck.md | 62 ++++++++++++++ .../feature-depth-xlsx-formula-check.md | 71 ++++++++++++++++ .../feature-depth-xlsx-insert-row.md | 73 +++++++++++++++++ ...ature-depth-xlsx-reader-structural-diff.md | 60 ++++++++++++++ ...ature-depth-xlsx-workbook-unpack-repack.md | 80 ++++++++++++++++++ ...-depth-agentos-sandbox-create-lifecycle.md | 62 ++++++++++++++ ...-depth-video-agent-managed-task-service.md | 71 ++++++++++++++++ ...ture-depth-yuanrong-agent-file-transfer.md | 60 ++++++++++++++ .../feature-depth-yuanrong-faas-invocation.md | 42 ++++++++++ ...pth-at-file-reference-inlining-b1a822e1.md | 82 +++++++++++++++++++ ...h-channel-security-review-slash-command.md | 71 ++++++++++++++++ ...feature-depth-gateway-config-hot-reload.md | 62 ++++++++++++++ .../feature-depth-gateway-health-check.md | 71 ++++++++++++++++ ...ure-depth-gateway-server-multi-route-ws.md | 62 ++++++++++++++ ...pth-im-attachment-persist-hook-969909e1.md | 53 ++++++++++++ .../feature-depth-im-channel-hot-reconfig.md | 62 ++++++++++++++ .../feature-depth-locale-conf-rpc.md | 71 ++++++++++++++++ .../feature-depth-thirdagent-list-switch.md | 80 ++++++++++++++++++ .../feature-depth-ide-file-edit-diff-apply.md | 51 ++++++++++++ .../feature-depth-ide-turn-rewind-snapshot.md | 62 ++++++++++++++ ...ature-depth-ide-terminal-command-mirror.md | 71 ++++++++++++++++ ...ture-depth-chat-session-stats-dashboard.md | 60 ++++++++++++++ ...feature-depth-code-mode-branch-selector.md | 62 ++++++++++++++ .../feature-depth-code-mode-commit-push.md | 60 ++++++++++++++ .../feature-depth-context-usage-indicator.md | 51 ++++++++++++ ...re-depth-frontend-incremental-lint-gate.md | 62 ++++++++++++++ .../feature-depth-rsi-experiment-ui.md | 62 ++++++++++++++ .../feature-depth-share-image-export.md | 71 ++++++++++++++++ .../feature-depth-web-asset-publish-flow.md | 71 ++++++++++++++++ .../feature-depth-web-i18n-zh-en.md | 71 ++++++++++++++++ ...ature-depth-web-native-directory-picker.md | 53 ++++++++++++ 93 files changed, 6020 insertions(+) create mode 100644 knowledge/repos/jiuwenswarm/components/agent-runtime/feature-depth-runtime-agent-definition-execution.md create mode 100644 knowledge/repos/jiuwenswarm/components/agent-runtime/feature-depth-session-input-steering.md create mode 100644 knowledge/repos/jiuwenswarm/components/agent-server-runtime/feature-depth-workspace-git-diff.md create mode 100644 knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-a2x-registry-client-sdk.md create mode 100644 knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-command-execution-tool.md create mode 100644 knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-dynamic-memory-cli.md create mode 100644 knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-llm-wiki-knowledge-base.md create mode 100644 knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-pdf-reading-tool.md create mode 100644 knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-sdd-design-rail.md create mode 100644 knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-session-messaging-toolkit.md create mode 100644 knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-user-todos-tool.md create mode 100644 knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-video-generation-tools.md create mode 100644 knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-web-search-tools.md create mode 100644 knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-alarm-crud.md create mode 100644 knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-calendar-tools.md create mode 100644 knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-call-phone-tool.md create mode 100644 knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-collection-tools.md create mode 100644 knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-contact-search.md create mode 100644 knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-location-tool.md create mode 100644 knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-note-tools.md create mode 100644 knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-photo-gallery-tools.md create mode 100644 knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-pushdata-store-and-viewer.md create mode 100644 knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-save-to-phone-tools.md create mode 100644 knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-timestamp-utc8-tool.md create mode 100644 knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-agent-template-layered-validation.md create mode 100644 knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-arxiv-visual-extraction.md create mode 100644 knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ascend-chrome-trace-generator.md create mode 100644 knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ascend-trace-analysis-pipeline.md create mode 100644 knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ascend-trace-auto-instrumentation.md create mode 100644 knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ascend-trace-compile-safety-checker.md create mode 100644 knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ascend-trace-instrumentation-planner.md create mode 100644 knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ascend-trace-preprocessor.md create mode 100644 knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-audit-integrity-hmac-signing.md create mode 100644 knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-audit-report-html-renderer.md create mode 100644 knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-cross-channel-history-search-skill.md create mode 100644 knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-daily-report-skill.md create mode 100644 knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-deepsearch-research-pipeline.md create mode 100644 knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-docx-pro-cli.md create mode 100644 knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-financial-document-parser.md create mode 100644 knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-github-issue-feedback-script.md create mode 100644 knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-huawei-maas-apikey-creation.md create mode 100644 knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-huawei-maas-cdp-authorize.md create mode 100644 knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-huawei-realname-account-check.md create mode 100644 knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-local-doc-ocr-offline.md create mode 100644 knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-maas-auto-open-models.md create mode 100644 knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-opc-add-slide.md create mode 100644 knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-opc-pack-validate.md create mode 100644 knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-plugin-package-initializer.md create mode 100644 knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-plugin-package-layered-validator.md create mode 100644 knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ppt-deck-finalize.md create mode 100644 knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ppt-evidence-preparation.md create mode 100644 knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ppt-execution-lock-validator.md create mode 100644 knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ppt-figure-panel-layout.md create mode 100644 knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ppt-opc-thumbnail.md create mode 100644 knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ppt-system-diagram-renderer.md create mode 100644 knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-pptx-structural-audit.md create mode 100644 knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-rsi-dataset-folder-check.md create mode 100644 knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-skill-generator-cli.md create mode 100644 knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-skill-page-scrape-blocks.md create mode 100644 knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-sop-structure-extraction.md create mode 100644 knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-video-coarse-scan-frame-extraction.md create mode 100644 knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-xlsx-add-computed-column.md create mode 100644 knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-xlsx-doctor-selfcheck.md create mode 100644 knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-xlsx-formula-check.md create mode 100644 knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-xlsx-insert-row.md create mode 100644 knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-xlsx-reader-structural-diff.md create mode 100644 knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-xlsx-workbook-unpack-repack.md create mode 100644 knowledge/repos/jiuwenswarm/components/extensions-plugins/feature-depth-agentos-sandbox-create-lifecycle.md create mode 100644 knowledge/repos/jiuwenswarm/components/extensions-plugins/feature-depth-video-agent-managed-task-service.md create mode 100644 knowledge/repos/jiuwenswarm/components/extensions-plugins/feature-depth-yuanrong-agent-file-transfer.md create mode 100644 knowledge/repos/jiuwenswarm/components/extensions-plugins/feature-depth-yuanrong-faas-invocation.md create mode 100644 knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-at-file-reference-inlining-b1a822e1.md create mode 100644 knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-channel-security-review-slash-command.md create mode 100644 knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-gateway-config-hot-reload.md create mode 100644 knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-gateway-health-check.md create mode 100644 knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-gateway-server-multi-route-ws.md create mode 100644 knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-im-attachment-persist-hook-969909e1.md create mode 100644 knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-im-channel-hot-reconfig.md create mode 100644 knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-locale-conf-rpc.md create mode 100644 knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-thirdagent-list-switch.md create mode 100644 knowledge/repos/jiuwenswarm/components/ide-clients/feature-depth-ide-file-edit-diff-apply.md create mode 100644 knowledge/repos/jiuwenswarm/components/ide-clients/feature-depth-ide-turn-rewind-snapshot.md create mode 100644 knowledge/repos/jiuwenswarm/components/ide-vscode/feature-depth-ide-terminal-command-mirror.md create mode 100644 knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-chat-session-stats-dashboard.md create mode 100644 knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-code-mode-branch-selector.md create mode 100644 knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-code-mode-commit-push.md create mode 100644 knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-context-usage-indicator.md create mode 100644 knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-frontend-incremental-lint-gate.md create mode 100644 knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-rsi-experiment-ui.md create mode 100644 knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-share-image-export.md create mode 100644 knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-web-asset-publish-flow.md create mode 100644 knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-web-i18n-zh-en.md create mode 100644 knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-web-native-directory-picker.md diff --git a/knowledge/repos/jiuwenswarm/components/agent-runtime/feature-depth-runtime-agent-definition-execution.md b/knowledge/repos/jiuwenswarm/components/agent-runtime/feature-depth-runtime-agent-definition-execution.md new file mode 100644 index 00000000..bb28be7a --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/agent-runtime/feature-depth-runtime-agent-definition-execution.md @@ -0,0 +1,71 @@ +--- +title: "声明式 root Agent 定义执行(invoke_agent/stream_agent):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/agent_definition.py:L159-L174, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/agent_definition.py:L117-L122, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/agent_definition.py:L161-L166, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/agent_definition.py:L288-L301, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/agent_definition.py:L304-L316, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/runtime/test_agent_definition.py:L41-L50, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/agent_definition.py:L265-L274, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/agent_definition.py:L319-L326, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/agent_definition.py:L276-L286, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/agent_definition.py:L252-L262, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/runtime/test_agent_definition.py:L244-L253, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/runtime/test_agent_definition.py:L277-L285] +feature: "runtime-agent-definition-execution" +entry_points: ["jiuwenswarm/runtime/service.py"] +source_globs: ["jiuwenswarm/runtime/service.py", "jiuwenswarm/runtime/agent_definition.py"] +--- + +# 声明式 root Agent 定义执行(invoke_agent/stream_agent):实现深读 + +[功能概览](feature-runtime-agent-definition-execution.md) · [owner 入口](_index.md) + + +**RuntimeAgentExecution 冻结 kw-only 数据类:fingerprint 代理 definition,to_dict 输出 JSON 兼容描述** +公开 fingerprint 属性直接返回 definition.fingerprint;to_dict 返回 {agent, agent_fingerprint, mode},其中 mode 经 _runtime_agent_mode 再次取 value。prepare_agent_execution 接受 definition 实例或 Mapping 加仅关键字 mode,返回不可变 RuntimeAgentExecution。 + +来源:[jiuwenswarm/runtime/agent_definition.py:L288–L301](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/runtime/agent_definition.py#L288-L301), [jiuwenswarm/runtime/agent_definition.py:L304–L316](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/runtime/agent_definition.py#L304-L316), [tests/unit_tests/runtime/test_agent_definition.py:L41–L50](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/runtime/test_agent_definition.py#L41-L50) + + + + + +**tools 默认 '*' 表示使用 Runtime 已配置的工具集** +RuntimeAgentDefinition 为 frozen/slots/kw_only 数据类,tools 默认值为 "*",skills 默认空元组,max_iterations 默认 None;docstring 说明 '*' 即复用 Runtime 配置的工具集。传入 ["*"] 列表也会归一化为 "*"。 + +来源:[jiuwenswarm/runtime/agent_definition.py:L159–L174](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/runtime/agent_definition.py#L159-L174), [jiuwenswarm/runtime/agent_definition.py:L117–L122](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/runtime/agent_definition.py#L117-L122) + + + + + +**agent_definition 契约模块声明为能力契约,由 AgentRuntime 翻译,自身不执行** +RuntimeAgentExecution 文档字符串说明它是 capability contract,AgentRuntime 将其翻译为既有 AgentManager 与 Agent Adapter 输入,而非第二个执行器;模块尾 __all__ 仅导出六个契约符号。 + +来源:[jiuwenswarm/runtime/agent_definition.py:L265–L274](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/runtime/agent_definition.py#L265-L274), [jiuwenswarm/runtime/agent_definition.py:L319–L326](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/runtime/agent_definition.py#L319-L326) + + + + + +**WORK_NORMAL/WORK_PLAN mode 触发 AGENT_DEFINITION_MODE_UNSUPPORTED(UNSUPPORTED_MODE,field=mode),非规范 mode 触发 INVALID_MODE** +__post_init__ 中 mode 解析失败抛 code=INVALID_MODE、field="mode" 的错误("unsupported single-Agent mode");命中 WORK_NORMAL/WORK_PLAN 抛 code=UNSUPPORTED_MODE、field="mode"("custom Agent definitions are not supported in work mode")。测试断言对应 code 且 retryable is False。 + +来源:[jiuwenswarm/runtime/agent_definition.py:L276–L286](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/runtime/agent_definition.py#L276-L286), [jiuwenswarm/runtime/agent_definition.py:L252–L262](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/runtime/agent_definition.py#L252-L262), [tests/unit_tests/runtime/test_agent_definition.py:L244–L253](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/runtime/test_agent_definition.py#L244-L253) + + + + + +**拒绝显式工具白名单:换取契约稳定,代价是暂时无法按 Agent 限权** +设计推断(非作者历史意图): + +实现注释写明拒绝 allowlist 是有意的,直到 Runtime 能在所有 rails 和扩展贡献完工具之后再 enforcing。推断(inference):收益是避免承诺无法执行的权限承诺,代价是定义方当前只能用全量工具集 '*'。 + +来源:[jiuwenswarm/runtime/agent_definition.py:L161–L166](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/runtime/agent_definition.py#L161-L166) + + + + + +**单元测试直接调用 prepare_agent_execution 断言 mode 错误码与先校验定义再校验 mode 能力** +test_work_modes_return_stable_unsupported_error 对两个 WORK mode 断言 AGENT_DEFINITION_MODE_UNSUPPORTED、field=mode、retryable False;test_prepare_accepts_mapping_and_validates_before_mode_capability 用非法 name 映射加 WORK_NORMAL 断言先得到 field=name 的 AGENT_DEFINITION_INVALID。这些是运行时断言,但仅覆盖契约校验层,未执行真实 Agent 执行。 + +来源:[tests/unit_tests/runtime/test_agent_definition.py:L244–L253](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/runtime/test_agent_definition.py#L244-L253), [tests/unit_tests/runtime/test_agent_definition.py:L277–L285](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/runtime/test_agent_definition.py#L277-L285) + + + diff --git a/knowledge/repos/jiuwenswarm/components/agent-runtime/feature-depth-session-input-steering.md b/knowledge/repos/jiuwenswarm/components/agent-runtime/feature-depth-session-input-steering.md new file mode 100644 index 00000000..f9493e70 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/agent-runtime/feature-depth-session-input-steering.md @@ -0,0 +1,80 @@ +--- +title: "Session Input Lane (steer/follow_up) and Execution Binding:实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/session_input.py:L58-L73, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/service.py:L2159-L2176, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/session_input.py:L65-L73, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/runtime/test_session_input.py:L257-L274, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/service.py:L1319-L1325, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/service.py:L1747-L1769, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/session_input.py:L33-L55, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/service.py:L1748-L1761] +feature: "session-input-steering" +entry_points: ["jiuwenswarm/runtime/service.py"] +source_globs: ["jiuwenswarm/runtime/service.py", "jiuwenswarm/runtime/session_input.py"] +--- + +# Session Input Lane (steer/follow_up) and Execution Binding:实现深读 + +[功能概览](feature-session-input-steering.md) · [owner 入口](_index.md) + + +**AgentRuntime.invoke delegates session-input requests to stream, which validates then routes CONTROL_INPUT to _deliver_control** +In invoke, when _is_session_input_request(request) is true the branch consumes self.stream(...) and returns only events whose payload is not None. In stream, after validate_session_input, a foreground-only guard, cross-session admission and session snapshot/state checks, session_work_kind returning CONTROL_INPUT routes the request to _deliver_control with the caller's on_control_event. + +来源:[jiuwenswarm/runtime/service.py:L1319–L1325](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/runtime/service.py#L1319-L1325), [jiuwenswarm/runtime/service.py:L1747–L1769](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/runtime/service.py#L1747-L1769) + + + + + +**validate_session_input caller obligations: non-empty query, steer-only binding, text-only steer** +validate_session_input(params) raises ValueError unless params['query'] is non-blank text; if 'expected_execution_id' is present it must be a non-empty string and resolve_session_input_mode(params) must be STEER; in STEER mode any non-empty images/image_files/files/attachments/audio_files/video_files raise ValueError("steering supports text only; send attachments as a queued task"). + +来源:[jiuwenswarm/runtime/session_input.py:L58–L73](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/runtime/session_input.py#L58-L73) + + + + + +**input_mode wins over the runtime_mode alias; both truthy and differing raises; unknown values fall back to None** +resolve_session_input_mode reads params['input_mode'] (primary) and params['runtime_mode'] (alias); if both are truthy and their normalized forms differ it raises ValueError('input_mode and runtime_mode must agree'), otherwise the primary (or alias when primary is falsy) is normalized and mapped to SessionInputMode, with unknown values returning None. The docstring notes interaction answers are classified separately before this intent. + +来源:[jiuwenswarm/runtime/session_input.py:L33–L55](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/runtime/session_input.py#L33-L55) + + + + + +**Supplement delivery requires an active agent exposing deliver_session_input** +Input delivery looks up the agent via agent_manager.get_agent_for_session_nowait(owner_channel, session_id); if no agent is found it raises SessionInputRejectedError("session has no active agent: ..."), and if the agent lacks a callable deliver_session_input it raises SessionInputRejectedError("active agent does not support supplemental input") before streaming. + +来源:[jiuwenswarm/runtime/service.py:L2159–L2176](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/runtime/service.py#L2159-L2176) + + + + + +**validate_session_input raises ValueError for blank query, non-steer expected_execution_id, and steer attachments** +If params contains expected_execution_id it must be a non-empty string and the resolved mode must be STEER, else ValueError; a query that is not a non-empty-trimmed string raises 'session input requires non-empty text'; in STEER mode any truthy value among images/image_files/files/attachments/audio_files/video_files raises 'steering supports text only; send attachments as a queued task'. Separately, stream raises ValueError for background session input and RuntimeStateError when the session snapshot is missing or in CLOSED/QUIESCING. + +来源:[jiuwenswarm/runtime/session_input.py:L58–L73](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/runtime/session_input.py#L58-L73), [jiuwenswarm/runtime/service.py:L1748–L1761](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/runtime/service.py#L1748-L1761) + + + + + +**Steering accepts text only: avoids silent attachment loss at the cost of a separate queued task** +设计推断(非作者历史意图): + +The comment at session_input.py:68-73 states the SDK's active steering queue carries text only, so non-empty attachment keys are rejected rather than acknowledged-and-dropped; the cost (design inference) is that callers with attachments must send them as an ordinary queued task instead of a steer. + +来源:[jiuwenswarm/runtime/session_input.py:L65–L73](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/runtime/session_input.py#L65-L73) + + + + + +**Automated runtime test asserts bound input keeps the original execution and returns its id** +test_bound_input_keeps_original_execution_and_returns_its_id (parametrized unary/stream) starts an original stream, snapshots the coordinator to get target execution_id, sends request(expected_execution_id=target), asserts events == [runtime.accepted] with payload['execution_id'] == target, exactly one CHAT_STREAM execution remains, original is not done and agent not cancelled, and the original's final event carries the same execution_id. + +来源:[tests/unit_tests/runtime/test_session_input.py:L257–L274](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/runtime/test_session_input.py#L257-L274) + + + diff --git a/knowledge/repos/jiuwenswarm/components/agent-server-runtime/feature-depth-workspace-git-diff.md b/knowledge/repos/jiuwenswarm/components/agent-server-runtime/feature-depth-workspace-git-diff.md new file mode 100644 index 00000000..3794ce2e --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/agent-server-runtime/feature-depth-workspace-git-diff.md @@ -0,0 +1,62 @@ +--- +title: "Workspace Git Diff Aggregation (get_git_diff):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/server/runtime/session/git_diff_watcher.py:L405-L444, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/server/utils/diff_service.py:L768-L777, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/server/test_diff_service.py:L570-L579, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/server/runtime/session/git_diff_status.py:L529-L544, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/server/runtime/session/git_diff_status.py:L1047-L1064, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/server/runtime/session/git_diff_status.py:L19-L20] +feature: "workspace-git-diff" +entry_points: ["jiuwenswarm/server/utils/diff_service.py"] +source_globs: ["jiuwenswarm/server/utils/diff_service.py", "jiuwenswarm/server/runtime/session/git_diff_watcher.py", "jiuwenswarm/server/runtime/session/git_diff_status.py"] +--- + +# Workspace Git Diff Aggregation (get_git_diff):实现深读 + +[功能概览](feature-workspace-git-diff.md) · [owner 入口](_index.md) + + +**build_turn_summary_entry returns None for falsy last_turn, else a dict with files fixed to {}** +Given a falsy last_turn the function returns None locally; otherwise it builds a dict copying kind/change_set_id/turn_index/status/stats with defaults (kind "conversation_turn", status "completed", empty ids) and "files" always {}. + +来源:[jiuwenswarm/server/runtime/session/git_diff_status.py:L1047–L1064](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/server/runtime/session/git_diff_status.py#L1047-L1064) + + + + + +**update_files_with_restore:快照-更新-on_snapshot 回调,回调抛错自动回滚并重抛** +调用方传入 async on_snapshot(watch) 计算首次快照并下发响应;回调抛出任何 Exception 且 previous_state 非空时执行 restore_files_state 后重新 raise。update_files 返回 None 或未传回调时直接返回。 + +来源:[jiuwenswarm/server/runtime/session/git_diff_watcher.py:L405–L444](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/server/runtime/session/git_diff_watcher.py#L405-L444) + + + + + +**项目目录解析顺序:channel_metadata.cwd → delivery_context.route_metadata.cwd → 顶层 project_dir** +_get_project_dir_from_metadata 按 docstring 声明的三步顺序任一命中即返回;测试证实仅顶层 project_dir 存在时返回该值,全部缺失时返回 None 而非抛错。 + +来源:[jiuwenswarm/server/utils/diff_service.py:L768–L777](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/server/utils/diff_service.py#L768-L777), [tests/unit_tests/server/test_diff_service.py:L570–L579](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/server/test_diff_service.py#L570-L579) + + + + + +**git_diff_status imports get_diff_service from server.utils.diff_service** +git_diff_status.py imports GitError/GitOperationError from project_git and get_diff_service from diff_service at module top; the shown span establishes only this import coupling, not call behavior. + +来源:[jiuwenswarm/server/runtime/session/git_diff_status.py:L19–L20](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/server/runtime/session/git_diff_status.py#L19-L20) + + + + + +**repo_is_dirty 兜底:以 git status 口径覆盖 diff 服务缺漏,代价是丢失 stats 明细** +设计推断(非作者历史意图): + +raw_diff 为空或非 dict 时返回 DiffSummary(is_dirty=repo_is_dirty, stats=DiffStats(), files={}):dirty 判定更权威(含 untracked),但该分支下统计与文件列表恒为空。(推断) + +来源:[jiuwenswarm/server/runtime/session/git_diff_status.py:L529–L544](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/server/runtime/session/git_diff_status.py#L529-L544) + + + diff --git a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-a2x-registry-client-sdk.md b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-a2x-registry-client-sdk.md new file mode 100644 index 00000000..1a10e86b --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-a2x-registry-client-sdk.md @@ -0,0 +1,71 @@ +--- +title: "A2X Registry Client SDK — mirrored sync/async service registry client:实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/team/a2x/client/client.py:L515-L530, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/team/a2x/client/client.py:L99-L107, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/team/a2x/client/async_client.py:L256-L281, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/team/a2x/client/async_client.py:L58-L60, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/team/a2x/client/client.py:L365-L388, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/agentserver/test_a2x_client_init.py:L272-L308] +feature: "a2x-registry-client-sdk" +entry_points: ["jiuwenswarm/agents/harness/team/a2x/client/__init__.py", "jiuwenswarm/agents/harness/team/a2x/client/async_client.py", "jiuwenswarm/agents/harness/team/a2x/client/client.py"] +source_globs: ["jiuwenswarm/agents/harness/team/a2x/client/__init__.py", "jiuwenswarm/agents/harness/team/a2x/client/async_client.py", "jiuwenswarm/agents/harness/team/a2x/client/client.py", "jiuwenswarm/agents/harness/team/a2x/client/_internal.py", "jiuwenswarm/agents/harness/team/a2x/client/errors.py", "jiuwenswarm/agents/harness/team/a2x/client/models.py", "jiuwenswarm/agents/harness/team/a2x/client/transport.py", "jiuwenswarm/agents/harness/team/a2x/client/ownership.py"] +--- + +# A2X Registry Client SDK — mirrored sync/async service registry client:实现深读 + +[功能概览](feature-a2x-registry-client-sdk.md) · [owner 入口](_index.md) + + +**Sync restore_to_blank for an owned agent: resolve endpoint, build blank card, replace card** +After the _assert_owned guard passes, _resolve_endpoint supplies the endpoint, build_blank_agent_card builds the card, and replace_agent_card overwrites the service; the docstring notes L3 raises ValueError when neither the L1 cache nor the current card yields an endpoint. + +来源:[jiuwenswarm/agents/harness/team/a2x/client/client.py:L365–L388](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/team/a2x/client/client.py#L365-L388) + + + + + +**release_my_lease:本地 _assert_owned 授权后 DELETE 租约路径,幂等返回 bool** +同步 A2XRegistryClient.release_my_lease(dataset, service_id) 先 _assert_owned(只能释放自己注册的 sid),随后 DELETE _i.service_lease_path(dataset, service_id),按响应 JSON 的 "released" 返回 bool;无租约时返回 False 而不报错。 + +来源:[jiuwenswarm/agents/harness/team/a2x/client/client.py:L515–L530](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/team/a2x/client/client.py#L515-L530) + + + + + +**create_dataset 的 embedding_model 默认取 _i.DEFAULT_EMBEDDING_MODEL** +A2XRegistryClient.create_dataset 的 embedding_model 参数默认值为 _internal.DEFAULT_EMBEDDING_MODEL,formats 默认 _i.UNSET;调用方未传时 body 由 _i.build_create_dataset_body 用这些默认值构造,POST 到 _i.DATASETS_ROOT。 + +来源:[jiuwenswarm/agents/harness/team/a2x/client/client.py:L99–L107](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/team/a2x/client/client.py#L99-L107) + + + + + +**replace_agent_card 遇 NotFoundError:清本地 owned/blank_endpoints 后原样上抛** +异步 replace_agent_card 在 POST a2a_register_path 抛 NotFoundError 时,await to_thread 移除 owned 条目并 pop _blank_endpoints 缓存,然后 re-raise;而 release_lease=True 时 release_my_lease 抛 A2XConnectionError/ServerError/NotFoundError 只 warnings.warn(租约靠 TTL 过期),注册结果仍正常返回。 + +来源:[jiuwenswarm/agents/harness/team/a2x/client/async_client.py:L256–L281](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/team/a2x/client/async_client.py#L256-L281) + + + + + +**Async client keeps _blank_endpoints cache lock-free, relying on event-loop serialization** +设计推断(非作者历史意图): + +Benefit (inference): the pure in-memory dict avoids per-access locking overhead. Cost: correctness depends on the event loop serializing access, per the code comment — the stated rationale is local to this implementation. + +来源:[jiuwenswarm/agents/harness/team/a2x/client/async_client.py:L58–L60](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/team/a2x/client/async_client.py#L58-L60) + + + + + +**Runtime helper test asserts blank-card replacement via a faked SDK client, not the real client** +test_teammate_destroy_restore_replaces_agent_card monkeypatches sys.modules so AsyncA2XRegistryClient is _FakeAsyncA2XRegistryClient, then asserts restore_teammate_blank_agent_on_destroy returns True, one client instance exists, closed is True, and card_replacements records dataset "team_pool", service_id "blank-service-id", a blank card with description "__BLANK__" and release_lease True. This validates the runtime helper against a mock; the real SDK's replace path is not exercised. NOT EXECUTED here. + +来源:[tests/unit_tests/agentserver/test_a2x_client_init.py:L272–L308](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/agentserver/test_a2x_client_init.py#L272-L308) + + + diff --git a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-command-execution-tool.md b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-command-execution-tool.md new file mode 100644 index 00000000..cd18a6bb --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-command-execution-tool.md @@ -0,0 +1,69 @@ +--- +title: "mcp_exec_command 跨平台命令执行工具:实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/command_tools.py:L1099-L1139, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/command_execution_context.py:L10-L42, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/command_execution_context.py:L57-L60, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/command_tools.py:L878-L884, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/command_runtime.py:L35-L60, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/command_tools.py:L1124-L1127, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/agents/test_command_tools_sandbox.py:L156-L168, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/agents/test_command_tools_sandbox.py:L56-L57, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/agents/test_command_tools_sandbox.py:L66-L104, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/command_tools.py:L20-L36] +feature: "command-execution-tool" +entry_points: ["jiuwenswarm/agents/harness/common/tools/command_tools.py"] +source_globs: ["jiuwenswarm/agents/harness/common/tools/command_tools.py", "jiuwenswarm/agents/harness/common/tools/command_execution_context.py", "jiuwenswarm/agents/harness/common/tools/command_runtime.py"] +--- + +# mcp_exec_command 跨平台命令执行工具:实现深读 + +[功能概览](feature-command-execution-tool.md) · [owner 入口](_index.md) + + +**mcp_exec_command 入口:空命令/安全检查/限流后解析 workdir 并钳制超时** +命令先 strip,为空返回 "[ERROR]: command cannot be empty.";随后 _check_command_safety 拒绝、按会话执行 TUI spawn 限流;_resolve_command_workdir 抛异常时返回 "[ERROR]: workdir is outside project workspace.";timeout_seconds 与环境变量上限(默认 600)取 min 后至少为 1。 + +来源:[jiuwenswarm/agents/harness/common/tools/command_tools.py:L1099–L1139](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/command_tools.py#L1099-L1139) + + + + + +**bind_command_execution(sys_operation, *, sandboxed) 返回 Token 并要求非空对象** +bind_command_execution 把 sys_operation 与布尔 sandboxed 存入冻结 dataclass 并经 ContextVar.set 返回 Token;sys_operation 为 None 抛 ValueError,sandboxed 非 bool 抛 TypeError。调用方须以 reset_command_execution(token) 还原。 + +来源:[jiuwenswarm/agents/harness/common/tools/command_execution_context.py:L10–L42](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/command_execution_context.py#L10-L42), [jiuwenswarm/agents/harness/common/tools/command_execution_context.py:L57–L60](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/command_execution_context.py#L57-L60) + + + + + +**JW_START_NEW_SESSION 默认启用子进程新会话(非 Windows)** +在 _run_command_sync 中,当 os.name != "nt" 时读取环境变量 JW_START_NEW_SESSION,默认 "true";仅当取值属于 ("0","false","no","off") 才不设置 popen_kw["start_new_session"]=True。 + +来源:[jiuwenswarm/agents/harness/common/tools/command_tools.py:L878–L884](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/command_tools.py#L878-L884) + + + + + +**mcp_exec_command 依赖 openjiuwen 进程注册表与 command_runtime 的路径契约** +command_tools.py 顶部从 openjiuwen shell_process_registry 导入注册/终止/取消消费函数,并复用 command_runtime.resolve_command_workdir:候选目录必须位于 project_root、workspace_root 或 agent_workspace_root 之内,否则抛出 ValueError("workdir is outside project workspace")。 + +来源:[jiuwenswarm/agents/harness/common/tools/command_tools.py:L20–L36](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/command_tools.py#L20-L36), [jiuwenswarm/agents/harness/common/tools/command_runtime.py:L35–L60](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/command_runtime.py#L35-L60) + + + + + +**workdir 越界抛 ValueError("workdir is outside project workspace")** +resolve_command_workdir 将候选路径 resolve 后须落在 project_root、可选 workspace_root 或 agent_workspace_root 之一内,否则抛 ValueError;工具层捕获后返回错误字符串且不调用 shell(测试断言 calls == [])。 + +来源:[jiuwenswarm/agents/harness/common/tools/command_runtime.py:L35–L60](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/command_runtime.py#L35-L60), [jiuwenswarm/agents/harness/common/tools/command_tools.py:L1124–L1127](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/command_tools.py#L1124-L1127), [tests/unit_tests/agents/test_command_tools_sandbox.py:L156–L168](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/agents/test_command_tools_sandbox.py#L156-L168) + + + + + +**沙箱绑定运行时测试:前台路径经 execute_cmd 且复位后绑定清除** +test_bound_sandbox_foreground_never_uses_host_subprocess 通过 mcp_exec_command._func 调用,断言 stdout 为 "A-stdout"、shell.calls 记录 ("printf ok", {cwd, timeout:17, shell_type:"bash"}),monkeypatch 使 _run_command_sync 触发 pytest.fail,且 reset 后 current_command_execution() 为 None。 + +来源:[tests/unit_tests/agents/test_command_tools_sandbox.py:L56–L57](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/agents/test_command_tools_sandbox.py#L56-L57), [tests/unit_tests/agents/test_command_tools_sandbox.py:L66–L104](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/agents/test_command_tools_sandbox.py#L66-L104) + + + diff --git a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-dynamic-memory-cli.md b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-dynamic-memory-cli.md new file mode 100644 index 00000000..6c35b7d8 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-dynamic-memory-cli.md @@ -0,0 +1,71 @@ +--- +title: "Dynamic Memory CLI(SQLite UT 记忆库与发布/构建流水线):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/dynamic-memory-cli/scripts/dynamic_memory_cli.py:L506-L511, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/dynamic-memory-cli/scripts/dynamic_memory_cli.py:L543-L546, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/dynamic-memory-cli/scripts/dynamic_memory_cli.py:L98-L100, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/rails/eternal_conversation/memory_cli.py:L70-L76, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/agentserver/rails/test_eternal_conversation_rail.py:L1166-L1172, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/agentserver/rails/test_eternal_conversation_rail.py:L759-L762, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/rails/eternal_conversation/memory_cli.py:L83-L106, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/rails/eternal_conversation/memory_cli.py:L126-L136, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/rails/eternal_conversation/memory_cli.py:L64-L80, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/rails/eternal_conversation/memory_cli.py:L43-L57, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/rails/eternal_conversation/memory_cli.py:L64-L107, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/dynamic-memory-cli/scripts/dynamic_memory_cli.py:L247-L250, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/rails/eternal_conversation/memory_cli.py:L115-L120] +feature: "dynamic-memory-cli" +entry_points: ["jiuwenswarm/resources/agent/workspace/skills/dynamic-memory-cli/scripts/dynamic_memory_cli.py"] +source_globs: ["jiuwenswarm/resources/agent/workspace/skills/dynamic-memory-cli/scripts/dynamic_memory_cli.py", "jiuwenswarm/agents/harness/common/rails/eternal_conversation/memory_cli.py"] +--- + +# Dynamic Memory CLI(SQLite UT 记忆库与发布/构建流水线):实现深读 + +[功能概览](feature-dynamic-memory-cli.md) · [owner 入口](_index.md) + + +**call() double-checks initialization, then _invoke() spawns the CLI and returns its parsed stdout JSON** +Under the init lock, if root/memory.sqlite3 is absent the gateway runs `init --path` without --root; _initialized is set only after that succeeds, so a failed init is retried on the next call. _invoke then runs [sys.executable, script, "--root", root, *args] with cwd=root, UTF-8 env overrides, stdin from DEVNULL, parses stdout as JSON, appends a memory-cli-calls audit entry, and raises RuntimeError when returncode != 0; otherwise it returns the parsed JSON value (whatever json.loads produced, not guaranteed to be a dict). + +来源:[jiuwenswarm/agents/harness/common/rails/eternal_conversation/memory_cli.py:L43–L57](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/rails/eternal_conversation/memory_cli.py#L43-L57), [jiuwenswarm/agents/harness/common/rails/eternal_conversation/memory_cli.py:L64–L107](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/rails/eternal_conversation/memory_cli.py#L64-L107) + + + + + +**CLI search() returns the single group for one query, {"queries": groups} otherwise; gateway search short-circuits blank queries** +CLI-side search(root, queries) computes one search_one group per query and returns groups[0] when len==1, else {"queries": groups}. Gateway-side search(query) strips the query and returns {"query": "", "matches": []} locally when empty; otherwise it dispatches `search ` through call(), a path a gateway comment says merges published Pending and Built UTs. + +来源:[jiuwenswarm/resources/agent/workspace/skills/dynamic-memory-cli/scripts/dynamic_memory_cli.py:L247–L250](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/dynamic-memory-cli/scripts/dynamic_memory_cli.py#L247-L250), [jiuwenswarm/agents/harness/common/rails/eternal_conversation/memory_cli.py:L115–L120](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/rails/eternal_conversation/memory_cli.py#L115-L120) + + + + + +**Root resolution and auto-init default; UTF-8 subprocess env** +--root is the global project option (init instead takes --path); commands other than init call require_project and raise ValueError("dynamic memory project not found at {root}") if the DB file is missing. The gateway forces PYTHONUTF8=1 and PYTHONIOENCODING=utf-8 on every CLI subprocess. + +来源:[jiuwenswarm/resources/agent/workspace/skills/dynamic-memory-cli/scripts/dynamic_memory_cli.py:L506–L511](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/dynamic-memory-cli/scripts/dynamic_memory_cli.py#L506-L511), [jiuwenswarm/resources/agent/workspace/skills/dynamic-memory-cli/scripts/dynamic_memory_cli.py:L543–L546](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/dynamic-memory-cli/scripts/dynamic_memory_cli.py#L543-L546), [jiuwenswarm/resources/agent/workspace/skills/dynamic-memory-cli/scripts/dynamic_memory_cli.py:L98–L100](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/dynamic-memory-cli/scripts/dynamic_memory_cli.py#L98-L100), [jiuwenswarm/agents/harness/common/rails/eternal_conversation/memory_cli.py:L70–L76](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/rails/eternal_conversation/memory_cli.py#L70-L76) + + + + + +**无效 JSON 与非零 returncode 在审计后抛 RuntimeError;取消时杀掉子进程再重抛** +_invoke 中 json.loads 失败时构造 {"error":"invalid_json",...} 结果、先 append_audit 再抛 RuntimeError;returncode != 0 时在审计后抛 "dynamic-memory-cli failed"。communicate() 期间收到 CancelledError 则 _stop_process 杀进程并重抛(returncode 已设置时直接返回)。 + +来源:[jiuwenswarm/agents/harness/common/rails/eternal_conversation/memory_cli.py:L83–L106](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/rails/eternal_conversation/memory_cli.py#L83-L106), [jiuwenswarm/agents/harness/common/rails/eternal_conversation/memory_cli.py:L126–L136](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/rails/eternal_conversation/memory_cli.py#L126-L136) + + + + + +**每次 call 起新子进程:换来进程隔离与 UTF-8 固定环境,代价是每命令的启动开销** +设计推断(非作者历史意图): + +(推断)每次 _invoke 都 create_subprocess_exec 一个新的 Python 解释器并强制 PYTHONUTF8=1、PYTHONIOENCODING=utf-8,受益是与 CLI 的编码和运行时隔离;代价是每条命令都付出解释器启动成本。这是对显示实现的推断,非文档记载的历史意图。 + +来源:[jiuwenswarm/agents/harness/common/rails/eternal_conversation/memory_cli.py:L64–L80](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/rails/eternal_conversation/memory_cli.py#L64-L80) + + + + + +**Runtime test: gateway search returns built UT after coordinator restart** +test (starting at line 1104 area, shown span 1166-1172) restarts SessionCoordinator on the same tmp_path, resumes background work, and asserts restarted.memory.search("NimbusGate")["matches"][0]["build_state"] == "built" — an actual runtime assertion through the gateway search path. NOT EXECUTED now; cited as existing test evidence. + +来源:[tests/unit_tests/agentserver/rails/test_eternal_conversation_rail.py:L1166–L1172](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/agentserver/rails/test_eternal_conversation_rail.py#L1166-L1172), [tests/unit_tests/agentserver/rails/test_eternal_conversation_rail.py:L759–L762](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/agentserver/rails/test_eternal_conversation_rail.py#L759-L762) + + + diff --git a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-llm-wiki-knowledge-base.md b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-llm-wiki-knowledge-base.md new file mode 100644 index 00000000..d03f8186 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-llm-wiki-knowledge-base.md @@ -0,0 +1,69 @@ +--- +title: "LLM Wiki 知识库(wiki_ingest/query/lint 子代理):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L536-L556, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L398-L415, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L42-L43, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L445-L459, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L20-L21, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L539-L558, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L569-L591, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/agents/test_wiki_tools_runtime_config.py:L30-L74, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L530-L558] +feature: "llm-wiki-knowledge-base" +entry_points: ["jiuwenswarm/agents/harness/common/tools/wiki_tools.py"] +source_globs: ["jiuwenswarm/agents/harness/common/tools/wiki_tools.py"] +--- + +# LLM Wiki 知识库(wiki_ingest/query/lint 子代理):实现深读 + +[功能概览](feature-llm-wiki-knowledge-base.md) · [owner 入口](_index.md) + + +**wiki_query 工具:解析 workspace → 构造 LLMWiki 子代理 → 调用 query 返回 output** +wiki_query 先用 _get_default_model() 取默认模型、_resolve_workspace(workspace) 解析出绝对路径;若该路径不存在则直接返回未初始化错误,否则经 _create_llm_wiki 构造 LLMWiki、ensure_initialized() 后调用 wiki.query(question=query),结果含 "output" 键时返回其字符串形式。 + +来源:[jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L536–L556](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/wiki_tools.py#L536-L556) + + + + + +**wiki_query 的输入校验与返回契约(局部返回分支)** +wiki_query(query, workspace="") 在 query 为空白时立即返回 "Error: Query cannot be empty.";workspace 解析后不存在时返回提示先用 wiki_ingest 初始化的错误字符串;否则调用 wiki.query 并按 result 中的 "output"/"error" 键返回字符串,兜底 JSON 序列化;异常被捕获并作为 "Wiki Query Error: ..." 字符串返回。 + +来源:[jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L530–L558](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/wiki_tools.py#L530-L558) + + + + + +**_resolve_workspace:空或等于 ".llm_wiki" 时回落到基础目录下的默认 wiki 目录** +workspace 字符串先 strip;为空或恰为 DEFAULT_WIKI_DIR(".llm_wiki")时返回 get_agent_workspace_dir()/.llm_wiki 的 resolve 结果;相对路径拼接到 base_dir,目录名不是 .llm_wiki 时追加该子目录,最终返回绝对路径。 + +来源:[jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L398–L415](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/wiki_tools.py#L398-L415), [jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L42–L43](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/wiki_tools.py#L42-L43) + + + + + +**_create_llm_wiki 依赖 openjiuwen 会话上下文派生子代理 session 血缘** +_create_llm_wiki 用 resolve_session_lineage(get_current_session()) 取 owner_session_id;存在时按 workspace 绝对路径 sha256 前 12 位拼出 "{owner}:subagent:wiki:{scope}" 作为 session_id 并传入 parent_session_id,再连同 workspace/model/sys_operation 传给 LLMWiki 构造器。 + +来源:[jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L445–L459](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/wiki_tools.py#L445-L459), [jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L20–L21](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/wiki_tools.py#L20-L21) + + + + + +**wiki_query/wiki_lint 的异常分支:workspace 缺失返回错误字符串,异常被捕获为错误文本** +两个工具在 final_workspace.exists() 为假时返回 "Error: The workspace ... does not have an initialized LLM Wiki."(不抛出);整体包在 try/except Exception 中,任何异常(含模型构造失败)被转为 "Wiki Query Error: {e}" / "Wiki Lint Error: {e}" 字符串返回给调用方。 + +来源:[jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L539–L558](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/wiki_tools.py#L539-L558), [jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L569–L591](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/wiki_tools.py#L569-L591) + + + + + +**_create_llm_wiki 的参数传播有 monkeypatch 单测覆盖(helper 级)** +test_create_llm_wiki_propagates_runtime_policy_and_parent_lineage 用 monkeypatch 替换 LLMWiki 捕获 kwargs,断言 enable_read_image_multimodal 为 False、session_id 为 "product-session:subagent:wiki:{workspace哈希前12位}"、parent_session_id 为 "product-session"、kv_cache_affinity_config.enable_kv_cache_affinity 为 True。LLMWiki 本体被 mock,测试只覆盖 _create_llm_wiki 这一 helper,不覆盖 wiki_ingest/query/lint 的运行时集成;未在本批次执行。 + +来源:[tests/unit_tests/agents/test_wiki_tools_runtime_config.py:L30–L74](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/agents/test_wiki_tools_runtime_config.py#L30-L74) + + + diff --git a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-pdf-reading-tool.md b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-pdf-reading-tool.md new file mode 100644 index 00000000..d77d7d1e --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-pdf-reading-tool.md @@ -0,0 +1,62 @@ +--- +title: "分页 PDF 文本读取工具(read_pdf):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L24-L26, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L117-L122, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L143-L143, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/agents/test_pdf_tools.py:L146-L159, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L239-L262, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L263-L275, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L125-L130, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L92-L101, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L143-L163, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L201-L208] +feature: "pdf-reading-tool" +entry_points: ["jiuwenswarm/agents/harness/common/tools/pdf_tools.py"] +source_globs: ["jiuwenswarm/agents/harness/common/tools/pdf_tools.py"] +--- + +# 分页 PDF 文本读取工具(read_pdf):实现深读 + +[功能概览](feature-pdf-reading-tool.md) · [owner 入口](_index.md) + + +**异步工具签名:必填 pdf_path,可选 pages 与 max_chars,返回 str** +read_pdf(pdf_path: str, pages: Any = None, max_chars: int = DEFAULT_MAX_CHARS, **kwargs) 为 @tool 注册的异步函数,返回 str;任何异常被捕获并返回 "[ERROR]: read_pdf failed: {exc}",kwargs 被忽略。 + +来源:[jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L239–L262](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/pdf_tools.py#L239-L262), [jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L263–L275](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/pdf_tools.py#L263-L275) + + + + + +**max_chars 默认 50_000,被钳制到 [1_000, 200_000],每次调用最多 100 页** +DEFAULT_MAX_CHARS = 50_000,_MAX_CHARS_CEILING = 200_000,_MAX_PAGES_PER_CALL = 100。_normalize_request 里 max_chars 取整失败回退默认值,再经 max(1_000, min(max_chars, 200_000)) 钳制;页选择在 _read_pdf_sync 中被 selected[:_MAX_PAGES_PER_CALL] 截断。 + +来源:[jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L24–L26](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/pdf_tools.py#L24-L26), [jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L117–L122](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/pdf_tools.py#L117-L122), [jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L143–L143](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/pdf_tools.py#L143-L143) + + + + + +**pdfplumber 延迟导入;相对路径依赖 openjiuwen get_workspace** +_read_pdf_sync 在路径校验之后才 import pdfplumber,使缺依赖环境仍能先报路径错误;_resolve_pdf_path 对非绝对路径导入 openjiuwen.core.sys_operation.cwd.get_workspace 拼接,取不到 workspace 时抛 ValueError。 + +来源:[jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L125–L130](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/pdf_tools.py#L125-L130), [jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L92–L101](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/pdf_tools.py#L92-L101) + + + + + +**每调用最多 100 页的上限换来输出有界,代价是超大文档必须分多次调用** +设计推断(非作者历史意图): + +selected 截断到 _MAX_PAGES_PER_CALL(100),被跳过的页会触发披露说明:当总页数不超过 100 时建议省略 pages 整读,否则提示从第一个未读页继续调用(推断:该设计以多次调用的代价控制单次返回规模)。 + +来源:[jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L143–L163](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/pdf_tools.py#L143-L163), [jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L201–L208](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/pdf_tools.py#L201-L208) + + + + + +**运行时单测直接 await read_pdf.invoke 断言输出内容** +test_read_pdf_extracts_pages_and_flags_blank 构造 3 页 PDF 后 await read_pdf.invoke({"pdf_path": ...}),断言 "total pages: 3"、"--- Page 1 ---"、页文本和 "no text layer" 均在结果中(pdfplumber 缺失时 importorskip 跳过)。此为证据所述测试内容,非本次执行结果。 + +来源:[tests/unit_tests/agents/test_pdf_tools.py:L146–L159](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/agents/test_pdf_tools.py#L146-L159) + + + diff --git a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-sdd-design-rail.md b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-sdd-design-rail.md new file mode 100644 index 00000000..efa4c400 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-sdd-design-rail.md @@ -0,0 +1,71 @@ +--- +title: "DesignRail SDD 状态机(Spec-Driven Development):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py:L76-L92, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py:L91-L92, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/sdd/design_rail/test_config_loader.py:L46-L47, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/sdd/design_rail/test_config_loader.py:L76-L83, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/sdd/design_rail/test_design_rail_integration.py:L121-L127, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py:L62-L92, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/code/rails/sdd/common/rail_state_machine.py:L40-L51, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py:L85-L90, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/code/rails/sdd/common/rail_state_machine.py:L261-L264, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py:L140-L149] +feature: "sdd-design-rail" +entry_points: ["jiuwenswarm/agents/harness/code/rails/sdd/common/rail_state_machine.py", "jiuwenswarm/agents/harness/code/rails/sdd/design_rail/__init__.py", "jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py"] +source_globs: ["jiuwenswarm/agents/harness/code/rails/sdd/common/rail_state_machine.py", "jiuwenswarm/agents/harness/code/rails/sdd/design_rail/__init__.py", "jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py", "jiuwenswarm/agents/harness/code/rails/sdd/design_rail/skills/aet-req-analysis/scripts/assemble-checklist.mjs", "jiuwenswarm/agents/harness/code/rails/sdd/design_rail/skills/aet-req-analysis/scripts/assemble-template.mjs", "jiuwenswarm/agents/harness/code/rails/sdd/design_rail/skills/aet-req-design/scripts/assemble-checklist.mjs", "jiuwenswarm/agents/harness/code/rails/sdd/design_rail/skills/aet-req-design/scripts/assemble-template.mjs", "jiuwenswarm/agents/harness/code/rails/sdd/design_rail/config_loader.py", "jiuwenswarm/agents/harness/code/rails/sdd/__init__.py", "jiuwenswarm/agents/harness/code/rails/sdd/common/__init__.py"] +--- + +# DesignRail SDD 状态机(Spec-Driven Development):实现深读 + +[功能概览](feature-sdd-design-rail.md) · [owner 入口](_index.md) + + +**DesignRail.__init__:加载并校验 rail_pkg_dir/config.yaml,失败抛 ValueError** +构造函数把 rail_pkg_dir/project_dir/priority 传给 super(),随后 config_loader.load(rail_pkg_dir / "config.yaml") 并 validate(带 rail_pkg_dir);result.ok 为假时 raise ValueError(f"DesignRail config validation failed: {result.errors}")。通过后 self.stages 取 cfg["stages"](空 dict 兜底)。 + +来源:[jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py:L76–L92](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py#L76-L92) + + + + + +**priority:config.yaml 的 priority 覆盖构造参数,缺省回退构造参数** +self._priority = int(cfg.get("priority", priority))——config.yaml 中的 priority 优先,未配置时使用 __init__ 传入的 priority(测试中为 60)。 + +来源:[jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py:L91–L92](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py#L91-L92), [tests/unit_tests/sdd/design_rail/test_config_loader.py:L46–L47](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/sdd/design_rail/test_config_loader.py#L46-L47) + + + + + +**DesignRail 继承 RailStateMachineBase,并在构造时依赖 config_loader 的 load+validate** +DesignRail 是 RailStateMachineBase 的子类(后者继承 openjiuwen 的 DeepAgentRail),构造函数调用 config_loader.load(rail_pkg_dir/config.yaml) 并用 validate(cfg, rail_pkg_dir=...) 校验后填充 self.stages。 + +来源:[jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py:L62–L92](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py#L62-L92), [jiuwenswarm/agents/harness/code/rails/sdd/common/rail_state_machine.py:L40–L51](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/code/rails/sdd/common/rail_state_machine.py#L40-L51) + + + + + +**config 校验失败时构造函数抛 ValueError;advance 非法 stage 返回 ok=False 字典** +__init__ 中 validate 结果不 ok 时 raise ValueError(含 errors 列表);_handle_advance 对非字符串或不属于 self.stages 的 stage 参数不抛异常,直接返回 {"ok": False, "error": f"invalid stage: {target!r}"} 交给调用方。 + +来源:[jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py:L85–L90](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py#L85-L90), [jiuwenswarm/agents/harness/code/rails/sdd/common/rail_state_machine.py:L261–L264](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/code/rails/sdd/common/rail_state_machine.py#L261-L264) + + + + + +**approve 不自动转移:避免双重推进,代价是依赖 agent 主动调用 sdd_advance** +设计推断(非作者历史意图): + +源码注释说明:若 after_tool_call 在 approve 时自动转移,随后 agent 再调 sdd_advance 会因已在下一阶段收到 "not a valid next" 错误;因此选择只记日志。收益是状态转移单一来源,成本是推进必须依赖 agent 遵循 SKILL.md R4 指令显式调用工具(此依赖为对该注释的推断性复述)。 + +来源:[jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py:L140–L149](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py#L140-L149) + + + + + +**单元/集成测试在运行时断言 validate 拒绝路径与 _handle_advance 成功转移** +自动化运行时验证:test_validate_no_path_init_to_done 构造 done 不可达的配置,断言 result.ok is False 且错误含 "no_path_init_to_done";集成测试用真实 config 构造 DesignRail 后调用 rail._handle_advance({"stage": "analysis_review"}),断言 result["ok"] is True 且 rail._stage == "analysis_review"。 + +来源:[tests/unit_tests/sdd/design_rail/test_config_loader.py:L76–L83](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/sdd/design_rail/test_config_loader.py#L76-L83), [tests/unit_tests/sdd/design_rail/test_design_rail_integration.py:L121–L127](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/sdd/design_rail/test_design_rail_integration.py#L121-L127) + + + diff --git a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-session-messaging-toolkit.md b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-session-messaging-toolkit.md new file mode 100644 index 00000000..38500d96 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-session-messaging-toolkit.md @@ -0,0 +1,80 @@ +--- +title: "跨会话消息 Agent 工具集(SessionMessagingToolkit 六工具):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/session_messaging_toolkit.py:L325-L342, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/session_messaging_toolkit.py:L287-L302, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/agentserver/test_session_messaging.py:L866-L882, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/session_messaging_toolkit.py:L358-L378, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/session_messaging_toolkit.py:L43-L67, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/session_messaging_toolkit.py:L330-L433, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/session_messaging_toolkit.py:L435-L445, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/session_messaging_toolkit.py:L594-L600, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/session_messaging_toolkit.py:L344-L356, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/session_messaging_toolkit.py:L358-L385, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/session_messaging_toolkit.py:L404-L418, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/session_messaging_toolkit.py:L330-L342, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/session_messaging_toolkit.py:L43-L54, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/session_messaging_toolkit.py:L350-L356] +feature: "session-messaging-toolkit" +entry_points: ["jiuwenswarm/agents/harness/common/tools/session_messaging_toolkit.py"] +source_globs: ["jiuwenswarm/agents/harness/common/tools/session_messaging_toolkit.py"] +--- + +# 跨会话消息 Agent 工具集(SessionMessagingToolkit 六工具):实现深读 + +[功能概览](feature-session-messaging-toolkit.md) · [owner 入口](_index.md) + + +**before_tool_call 回调按守卫绑定路由后再由 send_message 构造来源并调用服务** +before_tool_call 仅当工具名属于 _SESSION_MESSAGING_TOOL_NAMES 且路由含 session_id 与 request_id 时,把路由和 tool_call_id 写入上下文变量;send_message 随后用该 tool_call_id 调 source_for_call 并调用 service.send_message。 + +来源:[jiuwenswarm/agents/harness/common/tools/session_messaging_toolkit.py:L287–L302](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/session_messaging_toolkit.py#L287-L302), [jiuwenswarm/agents/harness/common/tools/session_messaging_toolkit.py:L358–L378](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/session_messaging_toolkit.py#L358-L378), [jiuwenswarm/agents/harness/common/tools/session_messaging_toolkit.py:L43–L67](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/session_messaging_toolkit.py#L43-L67) + + + + + +**六个工具方法签名各异,均要求服务与就绪路由,SessionMessagingError 转为结构化字典返回** +list_sessions/list_messages/continue_queued/read_session/resolve_message/send_message 均先经 _service_and_route,成功时透传 service 的 dict;send_message 额外要求上下文中已有 tool_call_id,失败时返回 {"accepted": False, "code": ..., "error": ...}。get_tools 首次构建后缓存并返回列表副本。 + +来源:[jiuwenswarm/agents/harness/common/tools/session_messaging_toolkit.py:L330–L433](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/session_messaging_toolkit.py#L330-L433), [jiuwenswarm/agents/harness/common/tools/session_messaging_toolkit.py:L435–L445](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/session_messaging_toolkit.py#L435-L445), [jiuwenswarm/agents/harness/common/tools/session_messaging_toolkit.py:L594–L600](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/session_messaging_toolkit.py#L594-L600) + + + + + +**工具入参默认值仅为本地签名默认:input_mode="steer"、limit 20/50、offset 0、cursor None、max_output_chars 4000** +send_message 的 input_mode 默认 "steer";list_sessions 默认 query=""、limit=20、offset=0;list_messages 默认 limit=50;read_session 默认 cursor=None、limit=20、max_output_chars=4000。这些是调用方未传参时的本地默认,非硬性上限。 + +来源:[jiuwenswarm/agents/harness/common/tools/session_messaging_toolkit.py:L344–L356](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/session_messaging_toolkit.py#L344-L356), [jiuwenswarm/agents/harness/common/tools/session_messaging_toolkit.py:L358–L385](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/session_messaging_toolkit.py#L358-L385), [jiuwenswarm/agents/harness/common/tools/session_messaging_toolkit.py:L404–L418](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/session_messaging_toolkit.py#L404-L418) + + + + + +**工具依赖运行时上下文中的 session_message_service 与路由上下文变量** +_service_and_route 优先用 set_service 注入的服务,否则从 get_current_runtime() 的 session_message_service 属性取;路由来自 _SESSION_MESSAGING_ROUTE 上下文变量(由 before_tool_call 在工具名匹配 _SESSION_MESSAGING_TOOL_NAMES 且路由含 session_id/request_id 时设置)。缺任一则抛 HOST_CAPABILITY_UNAVAILABLE。 + +来源:[jiuwenswarm/agents/harness/common/tools/session_messaging_toolkit.py:L325–L342](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/session_messaging_toolkit.py#L325-L342), [jiuwenswarm/agents/harness/common/tools/session_messaging_toolkit.py:L287–L302](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/session_messaging_toolkit.py#L287-L302) + + + + + +**服务缺失或路由不完整触发 HOST_CAPABILITY_UNAVAILABLE,空 tool_call_id 触发 MISSING_TOOL_CALL_ID** +_service_and_route 在 service 为 None 或路由缺 session_id/request_id 时抛 code 为 HOST_CAPABILITY_UNAVAILABLE 的 SessionMessagingError;source_for_call 在 tool_call_id 为空串时抛 MISSING_TOOL_CALL_ID。所示方法内这些异常被捕获并转为 accepted=False 的字典返回。 + +来源:[jiuwenswarm/agents/harness/common/tools/session_messaging_toolkit.py:L330–L342](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/session_messaging_toolkit.py#L330-L342), [jiuwenswarm/agents/harness/common/tools/session_messaging_toolkit.py:L43–L54](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/session_messaging_toolkit.py#L43-L54), [jiuwenswarm/agents/harness/common/tools/session_messaging_toolkit.py:L350–L356](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/session_messaging_toolkit.py#L350-L356) + + + + + +**每工具局部捕获 SessionMessagingError 换取 Agent 可读的错误码,代价是该异常不再向上传播** +设计推断(非作者历史意图): + +benefit:Agent 调用方直接拿到含 code 的结构化结果而非异常;cost:该异常在每个工具方法内被就地吞掉,且 except 仅覆盖 SessionMessagingError,其他异常类型不在该局部兜底内。此为基于所示实现的推断。 + +来源:[jiuwenswarm/agents/harness/common/tools/session_messaging_toolkit.py:L350–L356](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/session_messaging_toolkit.py#L350-L356), [jiuwenswarm/agents/harness/common/tools/session_messaging_toolkit.py:L358–L378](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/session_messaging_toolkit.py#L358-L378) + + + + + +**单元测试断言 read_session 分页、截断且不触发执行** +test(866-882 行)用临时 sqlite store 调 service.read_session(limit=2, max_output_chars=8),断言 newest_first 的 id 顺序 ["4","3"]、内容截断为 8 字符且无 private_metadata、游标翻页到 ["2","1"]、跨会话游标抛 SessionMessagingError、service._execute 未被 await。这是已存在的自动化运行时测试,本文未执行它。 + +来源:[tests/unit_tests/agentserver/test_session_messaging.py:L866–L882](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/agentserver/test_session_messaging.py#L866-L882) + + + diff --git a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-user-todos-tool.md b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-user-todos-tool.md new file mode 100644 index 00000000..475b07ce --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-user-todos-tool.md @@ -0,0 +1,62 @@ +--- +title: "user_todos Personal Per-Channel Todo Tool:实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/user_todo_tool.py:L17-L19, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/user_todo_tool.py:L109-L124, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/user_todo_tool.py:L270-L305, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/user_todo_tool.py:L208-L230, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/user_todo_tool.py:L246-L253, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/user_todo_tool.py:L13-L14, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/user_todo_tool.py:L194-L207, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/user_todo_tool.py:L114-L124] +feature: "user-todos-tool" +entry_points: ["jiuwenswarm/agents/harness/common/tools/user_todo_tool.py"] +source_globs: ["jiuwenswarm/agents/harness/common/tools/user_todo_tool.py"] +--- + +# user_todos Personal Per-Channel Todo Tool:实现深读 + +[功能概览](feature-user-todos-tool.md) · [owner 入口](_index.md) + + +**create action appends a TodoItem and writes the channel's file** +With title set, _handle_user_todos parses the channel file, derives remind_at = due_at − 5 minutes only when due_at is truthy, remind_at is unset and parses via datetime.fromisoformat (parse failure yields ""), appends a TodoItem with uuid[:8] id and status/priority defaulting to PENDING/MEDIUM, writes the file, and returns success with the new todo dict. + +来源:[jiuwenswarm/agents/harness/common/tools/user_todo_tool.py:L270–L305](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/user_todo_tool.py#L270-L305) + + + + + +**user_todos accepts a params object or dict and returns an operation result dict** +The @tool-decorated async function user_todos takes UserTodosParams (or a dict filtered to its dataclass fields) with action in list/get/create/update/delete/search, optional channel_id, and returns a Dict such as {"success": True, "todos": [...], "count": n} for list; the docstring notes channel_id defaults to the global channel id. + +来源:[jiuwenswarm/agents/harness/common/tools/user_todo_tool.py:L208–L230](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/user_todo_tool.py#L208-L230), [jiuwenswarm/agents/harness/common/tools/user_todo_tool.py:L246–L253](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/user_todo_tool.py#L246-L253) + + + + + +**Channel and workspace defaults: ContextVar channel "default", workspace "."** +Module defaults are _global_workspace_dir="." and a ContextVar channel_id defaulting to "default"; when params.channel_id is unset, _handle_user_todos falls back to _ctx_channel_id.get(), and todos live under /memory/user_todos/.md. Status/priority default to PENDING/MEDIUM on create. + +来源:[jiuwenswarm/agents/harness/common/tools/user_todo_tool.py:L17–L19](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/user_todo_tool.py#L17-L19), [jiuwenswarm/agents/harness/common/tools/user_todo_tool.py:L109–L124](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/user_todo_tool.py#L109-L124) + + + + + +**Registered via openjiuwen @tool as stateless=True; logging via jiuwenswarm logger** +The module imports the tool decorator from openjiuwen.core.foundation.tool.tool and logger from jiuwenswarm.common.utils (L13–L14). Registration uses stateless=True; the adjacent comment (L202–L205) states this is because the tool is a module-level singleton driven by set_global_workspace_dir/set_global_channel_id, so every agent shares one registration under its bare id — the comment's stated rationale, not runtime-verified here. + +来源:[jiuwenswarm/agents/harness/common/tools/user_todo_tool.py:L13–L14](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/user_todo_tool.py#L13-L14), [jiuwenswarm/agents/harness/common/tools/user_todo_tool.py:L194–L207](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/user_todo_tool.py#L194-L207) + + + + + +**Sanitization blocks path traversal but is not injective across channel ids** +设计推断(非作者历史意图): + +Benefit: _sanitize_channel_id strips path separators and special characters, preventing channel-id path traversal into other directories. Cost (inference): the substitution is many-to-one, so two distinct raw channel ids mapping to the same sanitized string would share one .md file; the shown code does not detect or prevent this collision. + +来源:[jiuwenswarm/agents/harness/common/tools/user_todo_tool.py:L114–L124](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/user_todo_tool.py#L114-L124) + + + diff --git a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-video-generation-tools.md b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-video-generation-tools.md new file mode 100644 index 00000000..95002442 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-video-generation-tools.md @@ -0,0 +1,80 @@ +--- +title: "generate_video / check_video_status Submit-then-Poll Video Generation:实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/video_gen_tools.py:L240-L264, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/video_gen_tools.py:L285-L319, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/video_gen_tools.py:L199-L207, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/video_gen_tools.py:L233-L238, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/video_gen_tools.py:L240-L245, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/video_gen_tools.py:L256-L264, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/video_gen_tools.py:L287-L297, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/video_gen_tools.py:L318-L319, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/video_gen_tools.py:L211-L222, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/video_gen_tools.py:L199-L199, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/agents/test_video_gen_tools.py:L16-L21, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/agents/test_video_gen_tools.py:L339-L349, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/agents/test_video_gen_tools.py:L276-L278, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/video_gen_tools.py:L352-L359, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/video_gen_tools.py:L285-L287, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/video_gen_tools.py:L37-L39] +feature: "video-generation-tools" +entry_points: ["jiuwenswarm/agents/harness/common/tools/video_gen_tools.py"] +source_globs: ["jiuwenswarm/agents/harness/common/tools/video_gen_tools.py", "jiuwenswarm/agents/harness/common/tools/gen_toolkits.py"] +--- + +# generate_video / check_video_status Submit-then-Poll Video Generation:实现深读 + +[功能概览](feature-video-generation-tools.md) · [owner 入口](_index.md) + + +**generate_video 默认分支:提交 POST {api_base}/videos 后轮询,完成则下载** +先取凭证并校验 prompt(video_gen_tools.py:240-248);detect_backend 无匹配时走默认 OpenRouter 风格分支:POST {api_base}/videos(287),非 200/201/202 即返回错误,否则取 job id 后经 _poll_job 轮询(301),completed 才调 _download_video(317),未到终态则返回含 job_id 的提示(306-310)。 + +来源:[jiuwenswarm/agents/harness/common/tools/video_gen_tools.py:L240–L264](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/video_gen_tools.py#L240-L264), [jiuwenswarm/agents/harness/common/tools/video_gen_tools.py:L285–L319](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/video_gen_tools.py#L285-L319) + + + + + +**generate_video 工具签名:扁平参数,默认 16:9 / 480p / 15 秒,返回 str** +签名为 prompt(必填 str)、aspect_ratio="16:9"、resolution="480p"、duration_seconds=15、first_frame_path=None、generate_audio=False、save_dir=None;返回文件路径字符串,或轮询窗口结束后仍运行时返回 job_id + 状态消息(docstring 236-238)。 + +来源:[jiuwenswarm/agents/harness/common/tools/video_gen_tools.py:L199–L207](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/video_gen_tools.py#L199-L207), [jiuwenswarm/agents/harness/common/tools/video_gen_tools.py:L233–L238](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/video_gen_tools.py#L233-L238) + + + + + +**凭证缺失时直接报错;后端由 VIDEO_GEN_PROTOCOL + api_base 探测分流** +凭证来自 _get_video_gen_api_credentials(),api_key/api_base/model 任一缺失即返回 "[ERROR]: video generation is not configured - set the Video processing API key, API URL, and model name..."(240-245);随后 detect_backend("VIDEO_GEN_PROTOCOL", api_base) 命中时把请求转给 gen_toolkits.submit_video(258-264),否则走内置 /videos 协议。 + +来源:[jiuwenswarm/agents/harness/common/tools/video_gen_tools.py:L240–L245](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/video_gen_tools.py#L240-L245), [jiuwenswarm/agents/harness/common/tools/video_gen_tools.py:L256–L264](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/video_gen_tools.py#L256-L264) + + + + + +**check_video_status backend branch delegates to gen_toolkits.check_video before its default httpx client** +When `backend` is truthy, check_video_status builds a gen_toolkits.GenerationTarget and returns `await gen_toolkits.check_video(target, job_id, save_dir)` at video_gen_tools.py:352-354, so that branch never reaches the module's own httpx client. The non-backend poll path instead constructs httpx.AsyncClient(timeout=30, verify=get_requests_verify()) (356-359), coupling its TLS verification to ssl_config.get_requests_verify; generate_video's submit uses the same verify helper with timeout=60 (285-287). + +来源:[jiuwenswarm/agents/harness/common/tools/video_gen_tools.py:L352–L359](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/video_gen_tools.py#L352-L359), [jiuwenswarm/agents/harness/common/tools/video_gen_tools.py:L285–L287](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/video_gen_tools.py#L285-L287), [jiuwenswarm/agents/harness/common/tools/video_gen_tools.py:L37–L39](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/video_gen_tools.py#L37-L39) + + + + + +**提交阶段四类失败均以 [ERROR] 字符串返回,不抛出** +非 200/201/202 → "[ERROR]: video generation submit failed: {status} {text}"(288-289);JSON 解析失败 → "...invalid JSON: {exc!r}"(290-293);缺 job id → "...returned no job id"(294-296);httpx.HTTPError 被 except 捕获 → "[ERROR]: video generation request failed: {exc!r}"(318-319)。 + +来源:[jiuwenswarm/agents/harness/common/tools/video_gen_tools.py:L287–L297](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/video_gen_tools.py#L287-L297), [jiuwenswarm/agents/harness/common/tools/video_gen_tools.py:L318–L319](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/video_gen_tools.py#L318-L319) + + + + + +**刻意保留扁平参数而非 BaseModel,换取 LLM 可见的工具 schema** +设计推断(非作者历史意图): + +docstring 自述:CallableSchemaExtractor 对 dataclass 只生成无属性的 {"type":"object"},BaseModel 虽可展开但会把顶层扁平参数改成嵌套对象、是对已验证工具的行为变更,故扁平签名是有意保留(211-222)。收益是模型能看到全部字段;成本是参数数量触发 pylint huawei-too-many-arguments 豁免(199)。此为基于 docstring 的推断。 + +来源:[jiuwenswarm/agents/harness/common/tools/video_gen_tools.py:L211–L222](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/video_gen_tools.py#L211-L222), [jiuwenswarm/agents/harness/common/tools/video_gen_tools.py:L199–L199](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/video_gen_tools.py#L199-L199) + + + + + +**单测直接调用 vg.generate_video._func,经 mock httpx 传输断言错误字符串** +测试取 @tool 包装内的原始异步函数(test 文件 16-21),如 test_generate_video_http_error_during_submit_is_caught 断言 ConnectError 时返回以 "[ERROR]: video generation request failed:" 开头的字符串(339-349),400 提交断言完整错误串(276-278)。 + +来源:[tests/unit_tests/agents/test_video_gen_tools.py:L16–L21](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/agents/test_video_gen_tools.py#L16-L21), [tests/unit_tests/agents/test_video_gen_tools.py:L339–L349](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/agents/test_video_gen_tools.py#L339-L349), [tests/unit_tests/agents/test_video_gen_tools.py:L276–L278](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/agents/test_video_gen_tools.py#L276-L278) + + + diff --git a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-web-search-tools.md b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-web-search-tools.md new file mode 100644 index 00000000..566c3fa7 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-web-search-tools.md @@ -0,0 +1,71 @@ +--- +title: "MCP Free/Paid Search Tools with Trusted-Search Provenance Lease:实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/trusted_search_tool_adapter.py:L36-L71, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/trusted_search_tool_adapter.py:L57-L66, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/agentserver/permissions/test_trusted_search_tool_adapter.py:L178-L186, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/agentserver/permissions/test_trusted_search_tool_adapter.py:L135-L151, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/agentserver/permissions/test_trusted_search_tool_adapter.py:L190-L216, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/agentserver/permissions/test_trusted_search_tool_adapter.py:L219-L240, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/search_tools.py:L31-L33, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/search_tools.py:L534-L548, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/search_tools.py:L31-L39, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/trusted_search_tool_adapter.py:L36-L48, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/trusted_search_tool_adapter.py:L82-L99, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/trusted_search_tool_adapter.py:L110-L114, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/search_tools.py:L565-L583] +feature: "web-search-tools" +entry_points: ["jiuwenswarm/agents/harness/common/tools/trusted_search_tool_adapter.py"] +source_globs: ["jiuwenswarm/agents/harness/common/tools/trusted_search_tool_adapter.py", "jiuwenswarm/channels/web/frontend/src/features/settings/modules/agent/AgentSettings.tsx", "jiuwenswarm/channels/web/frontend/src/features/settings/modules/agent/definition.ts", "jiuwenswarm/agents/harness/common/tools/search_tools.py"] +--- + +# MCP Free/Paid Search Tools with Trusted-Search Provenance Lease:实现深读 + +[功能概览](feature-web-search-tools.md) · [owner 入口](_index.md) + + +**mcp_free_search: strip query, clamp params, run provider in a thread, commit URLs, then render** +On invoke, the query is stripped (empty → "[ERROR]: query cannot be empty."), max_results is normalized and timeout clamped to [5,60]; run_free_search_structured runs via asyncio.to_thread, and on non-empty rows complete_trusted_search_producer(success=True, urls=...) commits row URLs before render_free_search_result returns the rendered string; a finally clause calls complete_trusted_search_producer(success=False). + +来源:[jiuwenswarm/agents/harness/common/tools/trusted_search_tool_adapter.py:L36–L71](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/trusted_search_tool_adapter.py#L36-L71) + + + + + +**mcp_free_search: string-returning tool with empty-query and provider-failure error strings (only the structured-search call is caught)** +mcp_free_search(query, max_results=8, timeout_seconds=20) strips the query and returns "[ERROR]: query cannot be empty." when blank; only exceptions from the asyncio.to_thread(run_free_search_structured) call are caught and returned as "[ERROR]: free search failed: {exc}". Empty result rows return "No search results for: {query}"; on success it calls complete_trusted_search_producer(success=True, urls=...) before render_free_search_result, and a finally block always calls complete_trusted_search_producer(success=False). + +来源:[jiuwenswarm/agents/harness/common/tools/trusted_search_tool_adapter.py:L36–L71](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/trusted_search_tool_adapter.py#L36-L71), [jiuwenswarm/agents/harness/common/tools/search_tools.py:L31–L33](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/search_tools.py#L31-L33) + + + + + +**Paid-provider availability from {PROVIDER}_API_KEY env vars in fixed fallback order** +configured_paid_search_providers() returns providers ("bocha", "perplexity", "serper", "jina") whose {PROVIDER}_API_KEY env var, uppercased and stripped, is nonblank. run_paid_search_structured defaults to provider="auto", max_results=DEFAULT_SEARCH_MAX_RESULTS (8) and timeout_seconds=45; mcp_free_search clamps max_results via normalize_search_max_results to [MIN_SEARCH_MAX_RESULTS=1, MAX_SEARCH_MAX_RESULTS=20] and timeout_seconds to [5, 60]. + +来源:[jiuwenswarm/agents/harness/common/tools/search_tools.py:L534–L548](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/search_tools.py#L534-L548), [jiuwenswarm/agents/harness/common/tools/search_tools.py:L31–L39](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/search_tools.py#L31-L39), [jiuwenswarm/agents/harness/common/tools/trusted_search_tool_adapter.py:L36–L48](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/trusted_search_tool_adapter.py#L36-L48) + + + + + +**Paid search guards: blank query, invalid provider, and provider exceptions return [ERROR] strings** +In _run_paid_search, a query that strips to empty returns "[ERROR]: query cannot be empty."; a provider outside {auto,bocha,jina,serper,perplexity} returns "[ERROR]: provider must be auto or a configured search provider."; any exception from run_paid_search_structured is returned as f"[ERROR]: {exc}". In every case the finally block still calls complete_trusted_search_producer(success=False). run_paid_search_structured raises RuntimeError("no paid search API keys configured.") when no provider key is nonblank, ValueError for an unknown provider, and collects "provider runner unavailable" errors per skipped runner. + +来源:[jiuwenswarm/agents/harness/common/tools/trusted_search_tool_adapter.py:L82–L99](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/trusted_search_tool_adapter.py#L82-L99), [jiuwenswarm/agents/harness/common/tools/trusted_search_tool_adapter.py:L110–L114](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/trusted_search_tool_adapter.py#L110-L114), [jiuwenswarm/agents/harness/common/tools/search_tools.py:L565–L583](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/search_tools.py#L565-L583) + + + + + +**Committing URLs before render survives render failure, at the cost of trusting URLs even if rendering then fails** +设计推断(非作者历史意图): + +Inference from the shown branch: success URLs are committed before render_free_search_result runs, so a render-time RuntimeError still leaves the URLs in the ledger (test raises "render failed" and then asserts ledger.contains(url)) — robust provenance, but committed URLs exist for output the caller never saw. + +来源:[jiuwenswarm/agents/harness/common/tools/trusted_search_tool_adapter.py:L57–L66](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/trusted_search_tool_adapter.py#L57-L66), [tests/unit_tests/agentserver/permissions/test_trusted_search_tool_adapter.py:L178–L186](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/agentserver/permissions/test_trusted_search_tool_adapter.py#L178-L186) + + + + + +**Automated runtime tests exercise both adapters' invoke with monkeypatched providers and assert lease/output state** +test_free_adapter_runs_normally_without_provenance_lease (lines 135-151) monkeypatches run_free_search_structured, awaits mcp_free_search.invoke({"query": "news"}), and asserts the URL appears in the result; test_provider_failure_consumes_lease_without_provenance (lines 219-240) asserts the "[ERROR]: free search failed: provider failed" string and len(ledger) == 0; test_paid_adapter_commits_only_structured_provider_urls (lines 190-216) asserts the exact rendered string and ledger.contains for both URLs. + +来源:[tests/unit_tests/agentserver/permissions/test_trusted_search_tool_adapter.py:L135–L151](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/agentserver/permissions/test_trusted_search_tool_adapter.py#L135-L151), [tests/unit_tests/agentserver/permissions/test_trusted_search_tool_adapter.py:L190–L216](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/agentserver/permissions/test_trusted_search_tool_adapter.py#L190-L216), [tests/unit_tests/agentserver/permissions/test_trusted_search_tool_adapter.py:L219–L240](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/agentserver/permissions/test_trusted_search_tool_adapter.py#L219-L240) + + + diff --git a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-alarm-crud.md b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-alarm-crud.md new file mode 100644 index 00000000..124d2a09 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-alarm-crud.md @@ -0,0 +1,71 @@ +--- +title: "设备闹钟 CRUD 工具(create/search/modify/delete_alarm):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py:L139-L169, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/runtime/test_runtime_xiaoyi_host_provider.py:L142-L161, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py:L593-L632, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py:L136-L163, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py:L603-L624, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L87-L97, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py:L626-L632, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L79-L85, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L168-L207, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py:L139-L159, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L168-L179, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L206-L207] +feature: "xiaoyi-alarm-crud" +entry_points: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py"] +source_globs: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py", "jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py", "jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py", "jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/contact_tools.py"] +--- + +# 设备闹钟 CRUD 工具(create/search/modify/delete_alarm):实现深读 + +[功能概览](feature-xiaoyi-alarm-crud.md) · [owner 入口](_index.md) + + +**delete_alarm:规范化输入后构造 DeleteAlarm 指令并等待设备响应** +delete_alarm 先调用 _normalize_delete_items 把 items/alarm_id 转成 entityId 列表,构造 bundleName 为 com.huawei.hmos.clock、intentName 为 DeleteAlarm 的 background 指令,再交给 execute_device_command 等待响应,随后经 raise_if_device_error 校验并取 result 组装成功返回。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py:L593–L632](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py#L593-L632), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py:L136–L163](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py#L136-L163) + + + + + +**_normalize_delete_items contract: alarm_id fallback only when items is None** +Items may be a JSON array string or a list; each element must be a dict with a non-empty string entityId or entity_id, and the result is never empty (empty list raises ToolInputError "items 不能为空"). + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py:L139–L169](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py#L139-L169) + + + + + +**delete_alarm 指令固定携带 timeOut: 5 与 executeMode: background** +delete_alarm 的指令不含可配置项:executeParam 硬编码 executeMode 为 "background"、timeOut 为 5、needUnlock 为 True;会话标识由 execute_device_command 从 config 的 channels.xiaoyi 下读取 last_session_id 与 last_task_id。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py:L603–L624](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py#L603-L624), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L87–L97](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py#L87-L97) + + + + + +**delete_alarm 依赖 execute_device_command 与运行时 Xiaoyi 通道** +delete_alarm 的设备交互完全委托给共享的 execute_device_command;该函数要求运行时存在 Xiaoyi 通道(否则 RuntimeError),并经 channel.send_xiaoyi_phone_tools_command 发送、以 intent_name 注册的数据事件处理器收响应,finally 中注销处理器。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py:L626–L632](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py#L626-L632), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L79–L85](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py#L79-L85), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L168–L207](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py#L168-L207) + + + + + +**双形态 items 输入便于 LLM 调用,代价是本地规范化分支更多** +设计推断(非作者历史意图): + +(推断)接受 JSON 字符串或原生列表、并用 alarm_id 单删兜底,让模型可用任一形态表达删除目标;代价是必须在 _normalize_delete_items 中逐一校验每条路径并抛出区分的 ToolInputError。execute_device_command 每次调用注册/注销事件处理器(finally 保证清理),换取按 intent_name 匹配响应。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py:L139–L159](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py#L139-L159), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L168–L179](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py#L168-L179), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L206–L207](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py#L206-L207) + + + + + +**Runtime test: device command with no active channel raises RuntimeError before config read** +test_device_command_rejects_missing_runtime_xiaoyi_channel installs a provider returning None and a get_config that fails the test if called, then asserts pytest.raises(RuntimeError, match="No active XY session found") around await utils.execute_device_command("TestIntent", ...) and lookups == ["xiaoyi"]. This exercises the shared command path, not the alarm tools' own bodies. + +来源:[tests/unit_tests/runtime/test_runtime_xiaoyi_host_provider.py:L142–L161](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/runtime/test_runtime_xiaoyi_host_provider.py#L142-L161) + + + diff --git a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-calendar-tools.md b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-calendar-tools.md new file mode 100644 index 00000000..83c046dd --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-calendar-tools.md @@ -0,0 +1,53 @@ +--- +title: "设备日历日程工具(create/search_calendar_event):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L113-L129, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L137-L164, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L166-L173, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L137-L160, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L244-L256, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L219-L229, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L265-L267, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L198-L207, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L210-L228, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L121-L125, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L72-L79] +feature: "xiaoyi-calendar-tools" +entry_points: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py"] +source_globs: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py"] +--- + +# 设备日历日程工具(create/search_calendar_event):实现深读 + +[功能概览](feature-xiaoyi-calendar-tools.md) · [owner 入口](_index.md) + + +**create_calendar_event:校验后构造命令并经 execute_device_command 下发** +校验 title/dt_start/dt_end 非空,strptime 按 %Y-%m-%d %H:%M:%S 转毫秒时间戳,构造 executeParam 后 await execute_device_command("CreateCalendarEvent", command);若 result 为 dict 才调用 raise_if_device_error,最后返回 format_success_response。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L113–L129](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py#L113-L129), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L137–L164](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py#L137-L164), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L166–L173](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py#L166-L173) + + + + + +**命令字面量硬编码:timeOut 5、bundleName com.huawei.hmos.calendardata** +两处命令构造均硬编码 executeMode="background"、timeOut 5、bundleName "com.huawei.hmos.calendardata";create 的 executeParam 不含 appType/permissionId,search 则含 appType="OHOS_APP" 与 permissionId=[]。所示片段内无外部配置读取。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L137–L160](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py#L137-L160), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L244–L256](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py#L244-L256) + + + + + +**输入错误抛 ToolInputError;设备错误码与超时分别转 RuntimeError 传播** +search 中 start_time/end_time 缺失或 _parse_time_string_ymd_hhmmss 抛 ValueError 时转为 ToolInputError 并原样重抛;设备 outputs 的 code 失败或 retErrCode 非 "0" 时 raise_if_device_error 抛 RuntimeError;execute_device_command 超时抛 asyncio.TimeoutError 转为 RuntimeError,finally 中注销事件处理器。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L219–L229](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py#L219-L229), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L265–L267](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py#L265-L267), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L198–L207](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py#L198-L207), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L210–L228](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py#L210-L228) + + + + + +**朴素 datetime 解析实现简单,但结果依赖主机本地时区** +设计推断(非作者历史意图): + +(推断)create 用 strptime+timestamp()、解析器用 datetime(...).timestamp()*1000,均按本地时区换算毫秒,实现简洁;代价是同一输入字符串在不同时区主机上产生不同的毫秒时间戳。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L121–L125](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py#L121-L125), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L72–L79](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py#L72-L79) + + + diff --git a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-call-phone-tool.md b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-call-phone-tool.md new file mode 100644 index 00000000..3687d8cc --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-call-phone-tool.md @@ -0,0 +1,62 @@ +--- +title: "小艺拨打电话工具 (call_phone):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L45-L107, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L24-L44, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L98-L107, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L46-L61, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L70-L82, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L14-L21, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L91-L96, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L171-L207, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L109-L113] +feature: "xiaoyi-call-phone-tool" +entry_points: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py"] +source_globs: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py"] +--- + +# 小艺拨打电话工具 (call_phone):实现深读 + +[功能概览](feature-xiaoyi-call-phone-tool.md) · [owner 入口](_index.md) + + +**call_phone 校验入参后构造 StartCall 命令并等待设备响应** +slot_id 为 None 时置 0;phone_number 非空字符串且 strip 后非空、slot_id 属于 (0, 1),否则抛 ToolInputError。随后构造 Common/Action、intentName=StartCall 的命令,交给 execute_device_command("StartCall", command),dict 化后经 raise_if_device_error 检查,成功返回 content 内嵌 outputs JSON 的响应。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L45–L107](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py#L45-L107) + + + + + +**async call_phone(phone_number: str, slot_id: Optional[int] = None) -> Dict[str, Any]** +用 @tool(name="call_phone") 注册;docstring 声明返回 success、code、phoneNumber、slotId、message(与设备成功回调字段一致),实际返回 {"content":[{"type":"text","text":<设备 outputs 的 JSON>}]}. 调用方须传有效 phone_number。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L24–L44](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py#L24-L44), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L98–L107](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py#L98-L107) + + + + + +**slot_id 未传时按 0(主卡),仅接受 0 或 1** +slot_id 默认 None,函数内 if slot_id is None: slot_id = 0;随后 slot_id not in (0, 1) 时抛 ToolInputError("slot_id 必须是 0(主卡)或 1(副卡)")。命令中另固定 timeOut: 5、executeMode: "background" 等字段,非可配置参数。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L46–L61](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py#L46-L61), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L70–L82](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py#L70-L82) + + + + + +**依赖 execute_device_command 与 raise_if_device_error,经频道 WebSocket 与设备通信** +call_phone 从 .utils 导入 execute_device_command、raise_if_device_error、ToolInputError,并经 openjiuwen 的 @tool 注册。execute_device_command 通过 channel.send_xiaoyi_phone_tools_command 发送并在 asyncio.wait_for(result_event.wait(), timeout=timeout) 内等响应;发送失败(sent 为假)抛 RuntimeError("发送指令失败,WebSocket 未连接"),finally 注销事件处理器。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L14–L21](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py#L14-L21), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L91–L96](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py#L91-L96), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L171–L207](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py#L171-L207) + + + + + +**统一包装为 RuntimeError 简化了非输入错误的对外类型,但调用方需经 __cause__ 区分原始异常** +设计推断(非作者历史意图): + +收益:非输入失败统一为 RuntimeError 并带中文上下文「拨打电话失败: …」;成本:调用方若需原始异常类型必须检查 __cause__(`from e` 已保留),不能仅凭被抛类型区分超时、设备错误等不同来源。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L109–L113](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py#L109-L113) + + + diff --git a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-collection-tools.md b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-collection-tools.md new file mode 100644 index 00000000..eff82cd6 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-collection-tools.md @@ -0,0 +1,53 @@ +--- +title: "小艺收藏/个人知识库工具 (query/add/delete_collection):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L293-L373, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L377-L384, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L165-L231, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L126-L146, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L217-L237, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L293-L303, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L386-L390, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L215-L231] +feature: "xiaoyi-collection-tools" +entry_points: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py"] +source_globs: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py"] +--- + +# 小艺收藏/个人知识库工具 (query/add/delete_collection):实现深读 + +[功能概览](feature-xiaoyi-collection-tools.md) · [owner 入口](_index.md) + + +**add_collection 校验入参后可先上传本地文件再下发 AddCollection 指令** +add_collection 先校验 dataType ∈ {HYPER_LINK,TEXT,IMAGE,FILE} 及对应必填字段;若 uri 不以 http://、https://、file:// 开头,则读取 channels.xiaoyi 配置上传换公网 URL,随后组装 executeMode=background、intentName=AddCollection 的 command,经 execute_device_command 执行,输出 dict 包成 content[0].text 的 JSON 字符串返回。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L293–L373](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py#L293-L373), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L377–L384](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py#L377-L384) + + + + + +**delete_collection 接受数组或 JSON 数组字符串的 item_ids,返回 content[0].text JSON** +delete_collection(item_ids: Union[str, List[str]]) 经 _normalize_item_ids 归一(None/非数组 JSON/其他类型抛 ToolInputError,空数组也抛 ToolInputError),成功时返回 {"content":[{"type":"text","text": json.dumps(outputs)}];调用方需提供非空 itemId 合集。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L165–L231](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py#L165-L231), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L126–L146](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py#L126-L146) + + + + + +**输入错误抛 ToolInputError 原样上抛,其余异常统一包成 RuntimeError** +delete_collection/add_collection 中 ToolInputError 被原样 re-raise(如 itemIds 为空、dataType 非法或对应字段缺失);任何其他 Exception 记录 error 日志后抛 RuntimeError("删除/添加小艺收藏失败: …") from e;设备返回的错误由 raise_if_device_error 以同样中文消息检查。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L217–L237](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py#L217-L237), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L293–L303](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py#L293-L303), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L386–L390](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py#L386-L390) + + + + + +**非 dict 输出兜底包一层 outputs,换取统一返回形状** +设计推断(非作者历史意图): + +收益:execute_device_command 返回非 dict 时包成 {"outputs": …},使后续 raise_if_device_error 与 JSON 序列化总有统一形状(推断:调用方解析逻辑因此更简单)。代价:原始标量输出被多包一层嵌套,调用方需知晓这一隐式包装约定(推断自 217-218、370-371 行的兜底分支)。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L215–L231](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py#L215-L231) + + + diff --git a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-contact-search.md b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-contact-search.md new file mode 100644 index 00000000..7060a75f --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-contact-search.md @@ -0,0 +1,69 @@ +--- +title: "设备联系人搜索工具(search_contact):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/contact_tools.py:L45-L96, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/contact_tools.py:L28-L47, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/contact_tools.py:L93-L102, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L76-L85, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/contact_tools.py:L18-L25, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/contact_tools.py:L56-L82, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L58-L62, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L87-L96, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/contact_tools.py:L45-L49, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/contact_tools.py:L98-L102, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L80-L85, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/contact_tools.py:L45-L47, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L53-L55] +feature: "xiaoyi-contact-search" +entry_points: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/contact_tools.py"] +source_globs: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/contact_tools.py"] +--- + +# 设备联系人搜索工具(search_contact):实现深读 + +[功能概览](feature-xiaoyi-contact-search.md) · [owner 入口](_index.md) + + +**search_contact 校验 name 后组装 SearchContactLocal 设备命令并格式化返回** +回调先校验 name 为非空字符串(否则抛 ToolInputError),strip 后记录日志,组装 namespace=Common/name=Action 的命令(intentName=SearchContactLocal、bundleName=com.huawei.hmos.aidispatchservice、timeOut=5、intentParam={"name": name_clean}),经 execute_device_command 取 outputs;非 dict 则包成 {"outputs": ...},从 result.items 数出条数,返回 format_success_response(dict(outputs), f"搜索到联系人信息({n} 条)")。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/contact_tools.py:L45–L96](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/contact_tools.py#L45-L96) + + + + + +**async def search_contact(name: str) -> Dict[str, Any]:单必填参数、成功返回设备 outputs 的包装** +经 openjiuwen @tool 注册为名为 "search_contact" 的工具,唯一参数 name(联系人姓名);文档承诺 Returns 的 content[0].text 为设备 outputs 的 JSON 字符串。name 非字符串或去空白后为空时抛 ToolInputError("缺少必填参数 name")且不被兜底 except 吞掉(ToolInputError 直接 re-raise)。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/contact_tools.py:L28–L47](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/contact_tools.py#L28-L47), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/contact_tools.py:L93–L102](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/contact_tools.py#L93-L102) + + + + + +**命令字段硬编码、intentParam.name 为唯一变量,会话标识从 channels.xiaoyi 配置读取** +executeParam 中 intentName=SearchContactLocal、bundleName、timeOut:5 等均硬编码,仅 intentParam.name 取自入参;execute_device_command 的 timeout 形参默认 60.0 秒;session_id 从 config 的 channels.xiaoyi.last_session_id 读取,task_id 初始为空串。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/contact_tools.py:L56–L82](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/contact_tools.py#L56-L82), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L58–L62](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py#L58-L62), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L87–L96](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py#L87-L96) + + + + + +**依赖 get_runtime_xiaoyi_channel() 返回的活动会话通道** +execute_device_command 首先取 get_runtime_xiaoyi_channel();返回 None 时直接抛 RuntimeError("No active XY session found. {intent_name} tool can only be used during an active conversation."),即该工具只能在活动小艺会话期间使用。search_contact 本身依赖 openjiuwen 的 @tool 装饰器与 jiuwenswarm.common.utils 的 logger。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L76–L85](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py#L76-L85), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/contact_tools.py:L18–L25](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/contact_tools.py#L18-L25) + + + + + +**空 name 抛 ToolInputError 原样上抛;无活动会话或设备执行异常时抛 RuntimeError** +name 非字符串或去空白后为空时抛 ToolInputError(status=400)并被 except ToolInputError: raise 原样传播;get_runtime_xiaoyi_channel() 返回 None 时抛 RuntimeError(无活动 XY 会话);其余任意异常被捕获并包装为 RuntimeError("搜索联系人失败: …") 后抛出。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/contact_tools.py:L45–L49](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/contact_tools.py#L45-L49), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/contact_tools.py:L98–L102](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/contact_tools.py#L98-L102), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L80–L85](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py#L80-L85) + + + + + +**区分输入错误与执行失败,但以 RuntimeError 统一包装其他异常类型** +search_contact 对空白 name 抛出 status=400 的 ToolInputError 并原样上抛,使参数错误与设备执行失败在类型上可区分;代价是其余任何 Exception 都被改写为 RuntimeError(搜索联系人失败: …),原始异常类型仅通过 `from e` 的 cause 链保留。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/contact_tools.py:L45–L47](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/contact_tools.py#L45-L47), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/contact_tools.py:L98–L102](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/contact_tools.py#L98-L102), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L53–L55](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py#L53-L55) + + + diff --git a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-location-tool.md b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-location-tool.md new file mode 100644 index 00000000..b0ba5af1 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-location-tool.md @@ -0,0 +1,51 @@ +--- +title: "设备定位工具(get_user_location):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py:L33-L86, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py:L34-L68, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L168-L207, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py:L16-L16, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py:L19-L31, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py:L68-L86] +feature: "xiaoyi-location-tool" +entry_points: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py"] +source_globs: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py"] +--- + +# 设备定位工具(get_user_location):实现深读 + +[功能概览](feature-xiaoyi-location-tool.md) · [owner 入口](_index.md) + + +**构建 GetCurrentLocation 指令并经设备通道等待响应** +无参协程先构造 namespace=Common/name=Action、intentName=GetCurrentLocation(isNeedGeoAddress=True、timeOut=5、executeMode=background)的命令 dict,调用 execute_device_command 等待 outputs;非 dict 则包成 {"value": outputs},经 raise_if_device_error 校验后以 content[0].text 返回 outputs 的 JSON 字符串(ensure_ascii=False)。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py:L33–L86](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py#L33-L86) + + + + + +**无参异步工具,返回设备 outputs 的 JSON 文本** +get_user_location 以 @tool(name="get_user_location") 注册,async 无参;成功时返回 {"content":[{"type":"text","text": json.dumps(outputs)}]},outputs 为 WebSocket 指令 GetCurrentLocation 的设备响应(非 dict 时包装为 {"value": outputs})。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py:L19–L31](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py#L19-L31), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py:L68–L86](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py#L68-L86) + + + + + +**指令参数在函数体内硬编码,无外部配置入口** +executeParam 各项(achieveType="INTENT"、bundleName="com.huawei.hmos.aidispatchservice"、intentName、timeOut=5、needUnlock=True 等)均为字面量硬编码;get_user_location 本身不接收也不读取任何配置。execute_device_command 的 timeout 由其自身默认/调用方决定,此处未传入。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py:L34–L68](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py#L34-L68) + + + + + +**依赖 execute_device_command 的 WebSocket 通道与事件处理** +工具将发送与等待全部委托给 execute_device_command:后者注册 intent_name 数据事件处理器,经 channel.send_xiaoyi_phone_tools_command 发送;sent 为假抛 RuntimeError("发送指令失败,WebSocket 未连接"),成功路径返回 result_data(None 时返回 {},注释明确勿用 or 短路),finally 中注销处理器。工具对通道协议的耦合即此两函数调用。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L168–L207](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py#L168-L207), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py:L16–L16](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py#L16-L16) + + + diff --git a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-note-tools.md b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-note-tools.md new file mode 100644 index 00000000..9050d8cf --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-note-tools.md @@ -0,0 +1,51 @@ +--- +title: "小艺备忘录工具 (create_note / search_notes / modify_note):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py:L107-L173, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py:L176-L204, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py:L35-L51, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py:L53-L80, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py:L211-L233, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py:L93-L97, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L210-L228, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L46-L55] +feature: "xiaoyi-note-tools" +entry_points: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py"] +source_globs: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py"] +--- + +# 小艺备忘录工具 (create_note / search_notes / modify_note):实现深读 + +[功能概览](feature-xiaoyi-note-tools.md) · [owner 入口](_index.md) + + +**search_notes 的完整执行路径:参数校验、构造 intent 命令、等待设备响应并包装返回** +search_notes(query) 先检查 query 为非空字符串并 strip 后非空,否则抛 ToolInputError;随后构造 namespace=Common/name=Action、intentName=SearchNote、bundleName=com.huawei.hmos.notepad 的命令,await execute_device_command("SearchNote", command) 取 outputs;非 dict 时包为 {"outputs": outputs},经 raise_if_device_error 检查后从 result.items 统计条数 n,返回 format_success_response(dict(outputs), f"搜索到 {n} 条备忘录")。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py:L107–L173](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py#L107-L173) + + + + + +**三个异步工具的契约:字符串入参、非空 guard、Dict 返回,modify_note 需先经 search_notes 取 entityId** +create_note(title, content)、search_notes(query)、modify_note(entity_id, text) 均为 async 函数返回 Dict[str, Any];每个参数都要求非空字符串(仅 search_notes 额外 strip,空白串抛 ToolInputError("query 不能为空"))。modify_note 的描述声明 entityId 必须先从 search_notes 获取,且设备侧字段名为 entityId。成功时返回经 format_success_response 包装的完整 outputs。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py:L176–L204](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py#L176-L204), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py:L35–L51](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py#L35-L51) + + + + + +**命令 payload 的固定字面量:executeMode=background、achieveType=INTENT、executeParam 内 timeOut=5** +三个工具的命令均为硬编码:executeParam 含 executeMode="background"、achieveType="INTENT"、needUnlock=True、actionResponse=True、timeOut=5,bundleName="com.huawei.hmos.notepad";payload 层(非 executeParam)固定 needUploadResult=True、noHalfPage=False、pageControlRelated=False。create/search 的 executeParam 不含 appType、permissionId,modify_note 则含 appType="OHOS_APP" 和 permissionId=[]。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py:L53–L80](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py#L53-L80), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py:L211–L233](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py#L211-L233) + + + + + +**输入错误原样抛出 ToolInputError,其余异常包装为 RuntimeError,设备错误码触发 RuntimeError** +三个工具中 except ToolInputError: raise 保持输入错误不变(其 status=400,文档称框架会返回 HTTP 400);其他任何 Exception 被记录日志并 raise RuntimeError(如 f"创建备忘录失败: {str(e)}")from e。raise_if_device_error 在 outputs 为 dict 且 code 检查不过或 retErrCode 非 "0" 时抛 RuntimeError(f"{what_failed}: {err_msg} …")。注意 create/modify 的非空 guard 接受纯空白字符串(仅 search_notes strip)。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py:L93–L97](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py#L93-L97), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L210–L228](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py#L210-L228), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L46–L55](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py#L46-L55) + + + diff --git a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-photo-gallery-tools.md b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-photo-gallery-tools.md new file mode 100644 index 00000000..c1b3d935 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-photo-gallery-tools.md @@ -0,0 +1,62 @@ +--- +title: "小艺图库搜索与照片上传工具 (search_photo_gallery / upload_photo):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L133-L151, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L192-L195, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L62-L130, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L88-L109, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L208-L229, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L58-L68, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L79-L97, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L111-L116, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L173-L229, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L234-L275, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L154-L156] +feature: "xiaoyi-photo-gallery-tools" +entry_points: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py"] +source_globs: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py"] +--- + +# 小艺图库搜索与照片上传工具 (search_photo_gallery / upload_photo):实现深读 + +[功能概览](feature-xiaoyi-photo-gallery-tools.md) · [owner 入口](_index.md) + + +**upload_photo 规范化入参后下发 ImageUploadForClaw 意令并返回解码后的公网 URL 列表** +upload_photo 先调用 _normalize_media_uris 将 media_uris 规范为列表;非空、≤5 条且每项为非空字符串时,构造 intentName 为 ImageUploadForClaw 的命令并 await execute_device_command。返回的 result.imageUrls 中的非字符串项被跳过,字符串 URL 经 _decode_image_url_escapes 替换 \u003d/\u0026 后,以 {imageUrls, count, message} 的 JSON 文本 content 返回。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L173–L229](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py#L173-L229), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L234–L275](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py#L234-L275), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L154–L156](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py#L154-L156) + + + + + +**search_photo_gallery(query: str) 校验非空字符串并包装设备 outputs 返回** +search_photo_gallery 接收单个 query 字符串,非字符串/为空/strip 后为空均抛 ToolInputError;设备 outputs 若非 dict 则包成 {"outputs": ...},经 raise_if_device_error 检查后按 result.items 数量以 format_success_response 返回完整 outputs。调用方需传入有效会话下可用的描述语料。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L62–L130](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py#L62-L130) + + + + + +**两工具命令硬编码 executeMode/timeOut,等待超时用 execute_device_command 默认 60 秒** +两个工具的 command 中 executeMode="background"、needUnlock=True、timeOut=5 均为硬编码;调用 execute_device_command 时未传 timeout,因此使用其签名默认 timeout=60.0 秒(文档注释称其为超时秒数)。所示片段不含覆盖该默认的配置项。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L88–L109](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py#L88-L109), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L208–L229](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py#L208-L229), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L58–L68](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py#L58-L68) + + + + + +**依赖运行时 XiaoyiChannel 与 config 的 xiaoyi 会话标识** +两个工具都通过 execute_device_command 执行;该函数从 get_runtime_xiaoyi_channel() 取通道,若为 None 抛 RuntimeError(提示仅能在活跃会话中使用),否则从 config 的 channels.xiaoyi 读取 last_session_id/last_task_id(默认空字符串)。所示片段未展示这些标识后续如何使用。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L79–L97](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py#L79-L97), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L111–L116](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py#L111-L116) + + + + + +**media_uris 兼容数组与 JSON 字符串带来灵活性,解析失败需调用方处理** +设计推断(非作者历史意图): + +(推断)_normalize_media_uris 同时接受 list 与 JSON 数组字符串,方便不同调用形态;代价是字符串解析失败抛 ToolInputError 且超 5 条需分批,把重试/分批负担转移给调用方。5 条上限本身是文档与代码一致的事实,代价部分为推断。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L133–L151](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py#L133-L151), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L192–L195](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py#L192-L195) + + + diff --git a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-pushdata-store-and-viewer.md b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-pushdata-store-and-viewer.md new file mode 100644 index 00000000..89043e93 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-pushdata-store-and-viewer.md @@ -0,0 +1,53 @@ +--- +title: "推送记录持久化与查询 (pushdata_manager + view_push_result):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/pushdata_manager.py:L34-L51, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/pushdata_manager.py:L67-L69, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/push_result_tool.py:L136-L152, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/push_result_tool.py:L49-L69, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/push_result_tool.py:L94-L134, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/pushdata_manager.py:L18-L19, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/pushdata_manager.py:L54-L66, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/push_result_tool.py:L49-L51, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/pushdata_manager.py:L56-L66, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/pushdata_manager.py:L49-L51] +feature: "xiaoyi-pushdata-store-and-viewer" +entry_points: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/push_result_tool.py", "jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/pushdata_manager.py"] +source_globs: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/push_result_tool.py", "jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/pushdata_manager.py"] +--- + +# 推送记录持久化与查询 (pushdata_manager + view_push_result):实现深读 + +[功能概览](feature-xiaoyi-pushdata-store-and-viewer.md) · [owner 入口](_index.md) + + +**view_push_result 关键词查询路径:剥离空白、全量/搜索取数、按 time 倒序后截断** +调用 view_push_result(keywords, limit) 时,先用 min(limit or 10, 50) 求 effective_limit,keywords 为非空字符串时取 strip 后的关键词;有关键词走 search_push_data,否则 get_all_push_data;结果按 item.get("time", "") 倒序排序后截取前 effective_limit 条,非空时逐条格式化为 pushDataId 前 8 位、fullPushDataId、time、dataDetail 超过 200 字符截断加 "..."、fullLength,并以 success/count/totalMatched/items/message 的 JSON 文本返回。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/push_result_tool.py:L49–L69](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/push_result_tool.py#L49-L69), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/push_result_tool.py:L94–L134](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/push_result_tool.py#L94-L134) + + + + + +**存储路径固定为 ~/.openclaw/pushData.json,写入选用最后 MAX_PUSHDATA_ITEMS=1000 条;查询条数默认 10、上限 50** +模块级常量 PUSHDATA_FILE = os.path.expanduser("~/.openclaw/pushData.json")、MAX_PUSHDATA_ITEMS = 1000;_write_pushdata_list 写入 items[-1000:],超出时记录 info 日志。view_push_result 中 effective_limit = min(limit or 10, 50),即 limit 为 None 或 0 时取 10,任何超过 50 的值被压到 50。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/pushdata_manager.py:L18–L19](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/pushdata_manager.py#L18-L19), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/pushdata_manager.py:L54–L66](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/pushdata_manager.py#L54-L66), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/push_result_tool.py:L49–L51](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/push_result_tool.py#L49-L51) + + + + + +**读失败降级为空列表、写失败上抛;工具层 except 兜底返回 success=False** +_read_pushdata_list 捕获 (json.JSONDecodeError, OSError) 记 error 日志并 return [];_write_pushdata_list 捕获 OSError 记日志后 raise;view_push_result 的 try 包住全部逻辑,任何 Exception 返回 {success: False, error: str(e), message: "查询推送记录失败"}。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/pushdata_manager.py:L34–L51](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/pushdata_manager.py#L34-L51), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/pushdata_manager.py:L67–L69](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/pushdata_manager.py#L67-L69), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/push_result_tool.py:L136–L152](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/push_result_tool.py#L136-L152) + + + + + +**记录条数封顶 1000 防止列表无限增长,但采用直接覆盖写(推断:非原子)且限制条数而非文件大小** +设计推断(非作者历史意图): + +写入限制在最后 1000 条(items[-MAX_PUSHDATA_ITEMS:]),防止记录无限累积(fact)。代价(推断):open(..., "w") 直接截断重写整个文件,进程中断可能留下部分写入的 JSON,后续读取会因 JSONDecodeError 降级为 [];且限制的是条数而非 dataDetail 长度,单条超长时文件仍可能很大。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/pushdata_manager.py:L56–L66](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/pushdata_manager.py#L56-L66), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/pushdata_manager.py:L49–L51](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/pushdata_manager.py#L49-L51) + + + diff --git a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-save-to-phone-tools.md b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-save-to-phone-tools.md new file mode 100644 index 00000000..507ab0dc --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-save-to-phone-tools.md @@ -0,0 +1,53 @@ +--- +title: "小艺保存到手机工具 (save_media_to_gallery / save_file_to_file_manager):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py:L29-L40, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/file_upload_helpers.py:L36-L92, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py:L43-L54, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/file_upload_helpers.py:L39-L43, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/file_upload_helpers.py:L60-L89, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py:L35-L40, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/file_upload_helpers.py:L60-L92, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py:L273-L277] +feature: "xiaoyi-save-to-phone-tools" +entry_points: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py"] +source_globs: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py", "jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/file_upload_helpers.py"] +--- + +# 小艺保存到手机工具 (save_media_to_gallery / save_file_to_file_manager):实现深读 + +[功能概览](feature-xiaoyi-save-to-phone-tools.md) · [owner 入口](_index.md) + + +**_get_obs_config 读取 channels.xiaoyi 的 file_upload_url/api_key/uid,但 uid 经 str() 转换削弱了缺失检查** +从 get_config() 取 cfg["channels"]["xiaoyi"],读取 file_upload_url、api_key、uid;三者传入非空检查,缺失时抛 ToolInputError("缺少 channels.xiaoyi 的 file_upload_url / api_key / uid 配置...")。但 uid 先执行 str(xc.get("uid")) 再判空:uid 为 None 时变成非空字符串 "None"、为 0 时变成 "0",因此该检查实际只可靠拦截 file_upload_url 与 api_key 的缺失。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py:L43–L54](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py#L43-L54) + + + + + +**Local paths depend on three-step OBS upload via shared aiohttp session** +_ensure_public_url 对非 http(s) 路径调用 upload_local_file_public_url:POST prepare(sha256/size 元数据)→ 按 uploadInfos[0] 的 method/url 直传文件 → POST completeAndQuery 取 fileDetailInfo.url;上传与设备命令均经由调用方创建的 aiohttp.ClientSession 或 execute_device_command 通道完成。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py:L29–L40](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py#L29-L40), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/file_upload_helpers.py:L36–L92](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/file_upload_helpers.py#L36-L92) + + + + + +**非 ToolInputError 异常在工具层被包装为 RuntimeError 后抛出** +上传 helper 中显式分支失败(prepare/upload/completeAndQuery HTTP 非 ok、code!="0"、无 uploadInfos、fileDetailInfo.url 为空)各自 raise RuntimeError(file_upload_helpers.py L60–92);工具函数里除 ToolInputError 原样上抛外,其余 Exception 记录日志并以 raise RuntimeError(...) from e 重新抛出(save_tools.py L273–277)。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/file_upload_helpers.py:L60–L92](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/file_upload_helpers.py#L60-L92), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py:L273–L277](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py#L273-L277) + + + + + +**本地文件全量读入内存并经三次串行请求换公网 URL:实现简单但内存与延迟成本随文件增大** +设计推断(非作者历史意图): + +(推断)收益:一次性 f.read() 使 sha256、fileSize 与上传体来自同一份内存内容,逻辑简单、无需流式分块。成本:整个文件驻留内存,且本地输入需顺序完成 prepare、文件传输、completeAndQuery 三次网络请求才拿到 URL,大文件时内存峰值与总延迟同时升高;http(s) 输入则完全跳过该路径。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/file_upload_helpers.py:L39–L43](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/file_upload_helpers.py#L39-L43), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/file_upload_helpers.py:L60–L89](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/file_upload_helpers.py#L60-L89), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py:L35–L40](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py#L35-L40) + + + diff --git a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-timestamp-utc8-tool.md b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-timestamp-utc8-tool.md new file mode 100644 index 00000000..3ade7a72 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-timestamp-utc8-tool.md @@ -0,0 +1,71 @@ +--- +title: "时间戳转北京时间工具 (convert_timestamp_to_utc8_time):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/timestamp_tool.py:L49-L69, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/timestamp_tool.py:L77-L84, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/timestamp_tool.py:L19-L38, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/timestamp_tool.py:L49-L60, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/timestamp_tool.py:L13-L16, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/timestamp_tool.py:L69-L75, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/timestamp_tool.py:L39-L47, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/timestamp_tool.py:L64-L67, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L46-L55, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/timestamp_tool.py:L50-L69] +feature: "xiaoyi-timestamp-utc8-tool" +entry_points: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/timestamp_tool.py"] +source_globs: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/timestamp_tool.py"] +--- + +# 时间戳转北京时间工具 (convert_timestamp_to_utc8_time):实现深读 + +[功能概览](feature-xiaoyi-timestamp-utc8-tool.md) · [owner 入口](_index.md) + + +**秒/毫秒时间戳经位宽启发式归一后转为北京时间字符串** +输入 timestamp 先经位宽判断(int 后字符串长 13 位视为毫秒、10 位视为秒,否则按 ts_abs>1000000000000 分流),乘 1000 归一为毫秒,再用固定 UTC+8 时区 datetime.fromtimestamp 转换并 strftime 为 "%Y%m%d %H%M%S",返回 content 列表字典。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/timestamp_tool.py:L49–L69](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/timestamp_tool.py#L49-L69), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/timestamp_tool.py:L77–L84](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/timestamp_tool.py#L77-L84) + + + + + +**@tool 注册、单一 timestamp: float 入参、返回 text content 字典** +函数经 openjiuwen @tool 装饰注册为名为 convert_timestamp_to_utc8_time 的工具,签名仅接受 timestamp: float;返回 {"content":[{"type":"text","text":格式化时间}]},文档字符串声明输出格式 YYYYMMDD hhmmss 并建议先转换再回答。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/timestamp_tool.py:L19–L38](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/timestamp_tool.py#L19-L38), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/timestamp_tool.py:L77–L84](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/timestamp_tool.py#L77-L84) + + + + + +**固定 UTC+8 与位数判定规则,无外部配置项** +时区固定为 timezone(timedelta(hours=8))(L63),输出格式固定为 "%Y%m%d %H%M%S"(L69)。秒/毫秒判定基于绝对值整数的字符串位数:13 位按毫秒,10 位按秒并乘 1000,超过 1000000000000 按毫秒,其余按秒乘 1000(L50–L60)。所示分支内未读取任何配置项,且输入为 None/非数字/NaN/Inf 时直接抛 ToolInputError,不会到达转换逻辑(L39–L47)。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/timestamp_tool.py:L50–L69](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/timestamp_tool.py#L50-L69), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/timestamp_tool.py:L39–L47](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/timestamp_tool.py#L39-L47) + + + + + +**导入 openjiuwen @tool、logger 与本包 ToolInputError;仅成功格式化后记录 INFO 日志** +L13–L16 显示三个直接依赖:tool 装饰器注册、logger、ToolInputError。日志(L71–L75)只在通过全部守卫且 fromtimestamp 成功后才执行;前置守卫抛错或 L65–L67 转换失败时不产生该 INFO 日志。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/timestamp_tool.py:L13–L16](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/timestamp_tool.py#L13-L16), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/timestamp_tool.py:L69–L75](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/timestamp_tool.py#L69-L75) + + + + + +**None、非数字、NaN/Inf 守卫与 fromtimestamp 的 OSError/OverflowError/ValueError 均抛 ToolInputError** +L39–L47 三条守卫各自抛 ToolInputError;L64–L67 的 try 仅包住 L65 的 fromtimestamp,捕获 OSError、OverflowError、ValueError 并包装为 ToolInputError 传播(携带 status=400,见 utils.py L53–L55)。不排除守卫之前其他未列异常。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/timestamp_tool.py:L39–L47](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/timestamp_tool.py#L39-L47), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/timestamp_tool.py:L64–L67](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/timestamp_tool.py#L64-L67), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L46–L55](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py#L46-L55) + + + + + +**位宽启发式同时接受秒/毫秒,但 11-12 位输入落入乘 1000 兜底** +设计推断(非作者历史意图): + +用 int 后十进制位宽(13/10)区分毫秒/秒并配数值兜底,收益是无需额外参数即可兼容两种位宽;代价是 11 或 12 位的时间戳既不匹配 13 也不匹配 10,落入 ts_abs>1000000000000 else 分支被强制视为秒乘 1000,可能产出错误时间(推断)。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/timestamp_tool.py:L49–L60](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/timestamp_tool.py#L49-L60) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-agent-template-layered-validation.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-agent-template-layered-validation.md new file mode 100644 index 00000000..3c826b95 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-agent-template-layered-validation.md @@ -0,0 +1,62 @@ +--- +title: "Agent 模板分层校验器(L0 规范 / L1 静态 AST / L2 子进程编排):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py:L949-L987, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_hot_load_worker.py:L328-L376, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_hot_load_worker.py:L140-L155, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py:L971-L987, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py:L151-L153, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py:L164-L173, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py:L956-L959, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py:L971-L977] +feature: "agent-template-layered-validation" +entry_points: ["jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py"] +source_globs: ["jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py", "jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_hot_load_worker.py"] +--- + +# Agent 模板分层校验器(L0 规范 / L1 静态 AST / L2 子进程编排):实现深读 + +[功能概览](feature-agent-template-layered-validation.md) · [owner 入口](_index.md) + + +**main():解析包目录后按层执行,热加载在静态错误时被跳过** +validate_template.py 的 main() 先 resolve_pkg 解析目标;validate_static 得到 quality/static 两层;若 --no-hot-load 或任一层有 errors,热加载层记录 skip 原因而非执行;随后逐层 render 输出并 _print_summary,仅当三层 status 均为 PASS 才返回 0,否则返回 1。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py:L949–L987](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py#L949-L987) + + + + + +**worker 子进程契约:单个包目录参数,stdout 输出 JSON 结果并按 status 返回 0/1/2** +validate_hot_load_worker.py 的 main() 要求 sys.argv 恰好为 2 个(脚本 + 包目录),否则打印 skip JSON 并返回 2;包目录不存在同样返回 2;结果以 json.dumps(result, ensure_ascii=False) 写到 stdout,status 为 pass 返回 0、fail 返回 1、其余(skip)返回 2。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_hot_load_worker.py:L328–L376](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_hot_load_worker.py#L328-L376) + + + + + +**数据目录默认 ~/.jiuwenswarm,target 先按路径再按 local/ 目录名解析,--no-hot-load 只跑 L0+L1** +get_jiuwenswarm_data_dir 在 raw 为真时对其 expanduser,否则默认 Path.home()/".jiuwenswarm"(所示行未给出 raw 的来源)。resolve_pkg 优先把 expanduser 后已是目录的参数 resolve 返回,否则尝试 local 模板目录下的同名目录,两处都不是目录时抛 FileNotFoundError。main 的 --no-hot-load(store_true)使 L2 直接记 skip(“已通过 --no-hot-load 显式跳过”),仅执行 L0+L1。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py:L151–L153](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py#L151-L153), [jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py:L164–L173](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py#L164-L173), [jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py:L956–L959](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py#L956-L959), [jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py:L971–L977](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py#L971-L977) + + + + + +**L2 热加载硬依赖 openjiuwen;导入失败被判为环境问题(skip)而非包问题** +worker 在执行真实加载链前导入 openjiuwen.core/harness 的 AgentCard、DeepAgent、Workspace 等符号;ImportError 时直接返回 _result("skip"),skip_fix 提示改用 JiuwenSwarm 的 venv python 重跑且这不是包的问题。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_hot_load_worker.py:L140–L155](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_hot_load_worker.py#L140-L155) + + + + + +**静态错误即跳过热加载:快速反馈的代价是静态失败时无运行时证据** +设计推断(非作者历史意图): + +main() 在 quality.errors 或 static.errors 非空时让热加载层 skip(提示先修 L0/L1 再重跑),这缩短了坏包的验证循环,但意味着静态未通过时本实现不产出任何热加载层的运行时结论。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py:L971–L987](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py#L971-L987) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-arxiv-visual-extraction.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-arxiv-visual-extraction.md new file mode 100644 index 00000000..dd63f75b --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-arxiv-visual-extraction.md @@ -0,0 +1,42 @@ +--- +title: "arXiv 论文 Figure/Table 检测与高清导出(extract_arxiv_visuals):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L1410-L1465, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L200-L246, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L55-L56, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L96-L112] +feature: "arxiv-visual-extraction" +entry_points: ["jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py"] +source_globs: ["jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py"] +--- + +# arXiv 论文 Figure/Table 检测与高清导出(extract_arxiv_visuals):实现深读 + +[功能概览](feature-arxiv-visual-extraction.md) · [owner 入口](_index.md) + + +**main():解析参数→解析输入→获取 PDF→签名校验→extract_visuals→输出摘要并返回 0** +main() 先校验参数,resolve_input 解析输入,本地 PDF 走 copy_local_pdf,否则 download_pdf;再读前 5 字节校验 %PDF- 后调用 extract_visuals,emit 结果计数与 manifest 路径,本地返回 0。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L1410–L1465](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py#L1410-L1465) + + + + + +**resolve_input:接受 arXiv ID/链接、HTTP(S) PDF 链接或本地 PDF 路径,否则 ValueError** +调用方传入原始字符串:本地文件后缀非 .pdf 抛 ValueError「本地文件不是 PDF」;命中 arXiv ID/URL 正则得到 pdf_url=https://arxiv.org/pdf/{id};其它 http(s) 链接按文件名生成 paper_id;都不匹配抛 ValueError 列出四种合法输入。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L200–L246](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py#L200-L246) + + + + + +**ensure_dependencies:import 探测 DEPENDENCIES,缺失且禁用自动安装时抛 RuntimeError** +对 DEPENDENCIES 表逐个 importlib.import_module,ImportError 记入 missing;auto_install=False 时拼出 pip install 命令并以 RuntimeError 抛出(含 sys.executable),由调用方决定安装。PIL 固定规格为 Pillow>=10,<13。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L55–L56](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py#L55-L56), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L96–L112](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py#L96-L112) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ascend-chrome-trace-generator.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ascend-chrome-trace-generator.md new file mode 100644 index 00000000..6e408fb6 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ascend-chrome-trace-generator.md @@ -0,0 +1,51 @@ +--- +title: "Chrome Trace JSON 生成器(trace_collector):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L367-L404, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L372-L379, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L375-L382, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L78-L88, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L384-L387] +feature: "ascend-chrome-trace-generator" +entry_points: ["jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py"] +source_globs: ["jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py", "jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_save.py", "jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_utils.py", "jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/inspect_rank_pt.py", "jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/bootstrap_trace_toolchain.py", "jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/verify_trace_scaffold.py"] +--- + +# Chrome Trace JSON 生成器(trace_collector):实现深读 + +[功能概览](feature-ascend-chrome-trace-generator.md) · [owner 入口](_index.md) + + +**main(): 解析参数后加载 rank 数据与 point_map,生成 chrome trace** +main() 配置日志、解析 CLI 参数,将 CLOCK_DIVISOR 设为 args.clock_divisor;load_all_ranks 读取 data_dir,若为空记录错误并 return;否则加载 mapping、打印诊断信息并调用 generate_chrome_trace(all_data, mapping, args.output, args.extra_mode, args.depth)。仅在 __main__ 时执行。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L367–L404](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py#L367-L404) + + + + + +**位置参数 data_dir 与 mapping_file,可选 -o/--output 等 CLI 契约** +CLI 需要两个位置参数:data_dir(含 rank*.pt 的目录)与 mapping_file(预处理器的 point_map.json);可选项 -o/--output、--clock-divisor、--extra-mode(choices=["legacy","seq"])、--depth。调用方需先产生 rank*.pt 与 point_map.json 才能运行。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L372–L379](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py#L372-L379) + + + + + +**默认 output=chrome_trace.json、clock-divisor=50.0、extra-mode=seq、depth=0** +argparse 默认值:--output 默认 "chrome_trace.json",--clock-divisor 默认 50.0(MHz 时钟频率),--extra-mode 默认 "seq"(仅允许 legacy/seq),--depth 默认 0 表示不过滤(0=all)。CLOCK_DIVISOR 全局变量在解析后被赋为该值。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L375–L382](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py#L375-L382) + + + + + +**缺失 point_map 文件会记录错误并返回空字典;空 rank 数据会中止主程序** +如果路径不存在,load_mapping 会记录 'ERROR: point_map not found' 并返回 {};如果 JSON 不是字典,它会记录 'point_map must be a JSON object' 并返回 {}。在 main 中,当 all_data 为空时会记录 'No rank*.pt files found' 并返回,不再进行后续生成。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L78–L88](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py#L78-L88), [jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L384–L387](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py#L384-L387) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ascend-trace-analysis-pipeline.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ascend-trace-analysis-pipeline.md new file mode 100644 index 00000000..edff8857 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ascend-trace-analysis-pipeline.md @@ -0,0 +1,82 @@ +--- +title: "ascend-moe-optimizer-trace-analyzer CLI 主流程:实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-trace-analyzer/analyzers/llm_analysis.py:L171-L221, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-trace-analyzer/app.py:L71-L90, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-trace-analyzer/app.py:L8-L34, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-trace-analyzer/app.py:L171-L197, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-trace-analyzer/app.py:L158-L170, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-trace-analyzer/app.py:L94-L99, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-trace-analyzer/analyzers/llm_analysis.py:L188-L221, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-trace-analyzer/SKILL.md:L157-L217] +feature: "ascend-trace-analysis-pipeline" +entry_points: ["jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-trace-analyzer/app.py"] +source_globs: ["jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-trace-analyzer/app.py", "jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-trace-analyzer/analyzers/phase_mapper.py", "jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-trace-analyzer/analyzers/diagnosis.py", "jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-trace-analyzer/analyzers/llm_analysis.py", "jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-trace-analyzer/analyzers/metrics.py", "jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-trace-analyzer/analyzers/parser.py", "jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-trace-analyzer/analyzers/plots.py", "jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-trace-analyzer/analyzers/reporter.py"] +--- + +# ascend-moe-optimizer-trace-analyzer CLI 主流程:实现深读 + +[功能概览](feature-ascend-trace-analysis-pipeline.md) · [owner 入口](_index.md) + + +**main() 在校验输入后依次解析 trace 并构建 PhaseMapper** +main() 先 parse_args(),再 validate_inputs()(文件不存在时抛 FileNotFoundError),ensure_dir(args.output_dir) 后调用 parse_trace_json/events_to_dicts 解析事件,最后用 PhaseMapper(args.phase_map) 构建 phase 映射;后续摘要构建与诊断表内容不在已展示行内,不展开。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-trace-analyzer/app.py:L158–L170](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-trace-analyzer/app.py#L158-L170), [jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-trace-analyzer/app.py:L94–L99](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-trace-analyzer/app.py#L94-L99) + + + + + +**run_llm_command(prompt, command, timeout_s=120) 契约:stdin 送 prompt,返回 status/analysis/error 字典** +调用方传入 prompt 字符串与 shell 命令字符串;命令经 shlex.split 后以 subprocess.run 执行,prompt 写入 stdin,capture_output 收集输出,check=False;成功时返回 {"status":"ok","analysis":stdout.strip(),"error":""},失败路径返回错误 status 与 error 文本。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-trace-analyzer/analyzers/llm_analysis.py:L171–L221](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-trace-analyzer/analyzers/llm_analysis.py#L171-L221) + + + + + +**LLM analysis is opt-in: --llm-analysis flag off by default, --llm-command default None, --llm-timeout default 120** +argparse defines --llm-analysis with action="store_true" (absent by default), --llm-command with default=None whose help says the command can alternatively come from TRACE_ANALYSIS_LLM_CMD, and --llm-timeout type=int default=120 described as the timeout in seconds for the --llm-analysis command. The shown span does not include the code that resolves --llm-command against the environment variable, so precedence is not established here. + +来源:[jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-trace-analyzer/app.py:L71–L90](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-trace-analyzer/app.py#L71-L90) + + + + + +**main() derives all summary tables from the single instances_df built by build_phase_instances** +app.py imports parser, PhaseMapper, eleven metrics builders, diagnosis and llm_analysis helpers, and reporter functions from the sibling analyzers modules; inside main(), phase/category/core-group/name/tid/overlap/bubble/overview outputs are all computed from instances_df, so a change in build_phase_instances' row shape propagates to every downstream table and to build_auto_diagnosis's inputs. + +来源:[jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-trace-analyzer/app.py:L8–L34](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-trace-analyzer/app.py#L8-L34), [jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-trace-analyzer/app.py:L171–L197](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-trace-analyzer/app.py#L171-L197) + + + + + +**run_llm_command converts only shlex, empty-command, FileNotFoundError, TimeoutExpired and nonzero exit into status dicts** +shlex.split raising ValueError returns {status: "error", error: f"Invalid LLM command: {exc}"}; an empty argv returns {status: "not_configured", error: "Empty LLM command."}; subprocess.run's FileNotFoundError and TimeoutExpired (after timeout_s, default 120) return status "error"/"timeout" respectively; a nonzero returncode returns stderr or a code message. Only these branches are guarded; other exceptions from subprocess.run would propagate uncaught. + +来源:[jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-trace-analyzer/analyzers/llm_analysis.py:L171–L221](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-trace-analyzer/analyzers/llm_analysis.py#L171-L221) + + + + + +**run_llm_command 以 check=False 加状态字典返回,非零退出不抛异常但丢弃其 stdout** +设计推断(非作者历史意图): + +run_llm_command 用 subprocess.run(check=False) 运行外部 LLM 命令:收益是非零退出不抛异常而是返回 {"status":"error", "error": stderr 或退出码信息};代价是失败分支不返回 result.stdout,超时/找不到可执行文件分支同样 analysis 为空字符串。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-trace-analyzer/analyzers/llm_analysis.py:L188–L221](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-trace-analyzer/analyzers/llm_analysis.py#L188-L221) + + + + + +**SKILL.md 记录的基础验证命令(documented_manual,未执行)** +文档中的人工验收步骤(本轮未执行): + +SKILL.md「依赖和验证」节给出基础验证步骤:cd 到 skill 根目录后运行 python3 app.py --trace --phase-map --output-dir --top-n 20,预期是完成一次分析运行。该文档还声明默认运行只用 Python 标准库。这是已记录的手工过程,本次未执行;未提供针对 app.py 的自动化测试证据。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-trace-analyzer/SKILL.md:L157–L217](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-trace-analyzer/SKILL.md#L157-L217) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ascend-trace-auto-instrumentation.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ascend-trace-auto-instrumentation.md new file mode 100644 index 00000000..f3d34cb0 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ascend-trace-auto-instrumentation.md @@ -0,0 +1,53 @@ +--- +title: "TRACE_POINT 自动埋点改写(instrument_operator):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py:L108-L125, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py:L101-L105, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py:L111-L115, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py:L61-L64, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py:L82-L84, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py:L48-L58, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py:L74-L89, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py:L67-L68, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py:L82-L86] +feature: "ascend-trace-auto-instrumentation" +entry_points: ["jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py"] +source_globs: ["jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py"] +--- + +# TRACE_POINT 自动埋点改写(instrument_operator):实现深读 + +[功能概览](feature-ascend-trace-auto-instrumentation.md) · [owner 入口](_index.md) + + +**CLI: --target 必填,--root-label 默认 processing,--dry-run 仅预览** +main 通过 argparse 要求 --target(文件或目录),可选 --root-label 与 --dry-run;iter_targets 在目录模式下仅收集后缀为 .h/.hpp/.c/.cc/.cpp 的文件,apply_file 返回 (计数, 消息) 并由 logger.info 逐文件输出。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py:L108–L125](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py#L108-L125), [jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py:L101–L105](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py#L101-L105) + + + + + +**--root-label 默认 processing,函数名 process 例外使用根标签** +--root-label 默认值为 "processing"(argparse default);apply_file 中仅当函数名小写等于 "process" 时使用 root_label,其他函数用 normalize_label 把驼峰/下划线转为小写连字符标签。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py:L111–L115](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py#L111-L115), [jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py:L61–L64](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py#L61-L64), [jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py:L82–L84](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py#L82-L84) + + + + + +**未匹配闭括号时 find_match_brace 兜底返回 len(text)-1;无函数/已埋点时跳过** +find_match_brace 扫描到文本末尾仍未配平时返回 len(text)-1(不抛错,end 语句可能插入到文件末字符前);apply_file 在 find_functions 为空时返回 (0, "skip ... (no function found)"),全部函数已含埋点时返回 (0, "skip ... (already instrumented)"),两种情况均不写文件。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py:L48–L58](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py#L48-L58), [jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py:L74–L89](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py#L74-L89) + + + + + +**子串级幂等跳过实现零依赖,但启发式识别可能漏配或错配** +设计推断(非作者历史意图): + +收益:should_skip 用子串判断即可避免重复插入,且只改写文件、无外部依赖。代价(推断):FUNC_RE/括号计数忽略字符串与注释内容,未匹配到闭括号时 find_match_brace 回退返回 len(text)-1,end 语句可能插在最后一个字符之前;识别为启发式,不保证覆盖所有 C++ 函数形式。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py:L48–L58](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py#L48-L58), [jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py:L67–L68](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py#L67-L68), [jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py:L82–L86](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py#L82-L86) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ascend-trace-compile-safety-checker.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ascend-trace-compile-safety-checker.md new file mode 100644 index 00000000..581d9d50 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ascend-trace-compile-safety-checker.md @@ -0,0 +1,71 @@ +--- +title: "插桩编译安全静态检查器:实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py:L271-L285, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py:L292-L301, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py:L265-L265, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py:L287-L301, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py:L258-L260, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py:L64-L73, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py:L42-L44, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py:L55-L73, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py:L76-L88, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py:L258-L266, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py:L47-L48, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py:L264-L264, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py:L271-L283] +feature: "ascend-trace-compile-safety-checker" +entry_points: ["jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py"] +source_globs: ["jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py", "jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/run_instrumentation_checks.sh", "jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/validate_trace_points.py"] +--- + +# 插桩编译安全静态检查器:实现深读 + +[功能概览](feature-ascend-trace-compile-safety-checker.md) · [owner 入口](_index.md) + + +**main() 遍历算子目录下 .cpp/.h/.hpp(排除 build_out/pregen)并逐项运行检查** +main() 对 operator_dir 执行 rglob 收集 .cpp/.h/.hpp,过滤含 build_out 或 pregen 的路径,对每个文件跑 brace/preprocessor/trace-point/scope/profiling 检查,再对 op_kernel 文件做 header 可达性与 kernel 输出一致性检查,最后输出 warnings/errors 并在通过时打印 PASSED。单个 brace 检查内部发现 depth<0 时记录一条 error 后 return,仅跳过该文件剩余行,不影响其他文件。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py:L271–L285](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py#L271-L285), [jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py:L292–L301](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py#L292-L301) + + + + + +**CLI 契约:位置参数 operator_dir 与可选 --strict,失败时 sys.exit(1)** +main() 通过 argparse 接受位置参数 operator_dir(应含 op_kernel/ 与 op_host/ 的算子根目录)和可选 --strict;当存在 error,或 --strict 且有 warning 时,记 FAILED 并在 main 内调用 sys.exit(1),否则输出 PASSED 汇总日志。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py:L258–L266](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py#L258-L266), [jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py:L292–L301](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py#L292-L301) + + + + + +**唯一可配置项是 --strict;默认 warnings 不影响通过,--strict 时计入失败** +默认(无 --strict)下 result.ok 只取决于 errors 是否为空,warnings 仅逐条经 logger.warning 输出;--strict 且存在 warnings 时进入失败分支,error_count = errors + warnings 并 sys.exit(1)。日志仅在 root logger 无 handlers 时 basicConfig(level=INFO)。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py:L265–L265](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py#L265-L265), [jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py:L287–L301](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py#L287-L301), [jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py:L258–L260](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py#L258-L260) + + + + + +**对算子目录布局与文件名子串的耦合;读文件按 UTF-8 容错解码** +main 依赖 operator_dir 的目录布局:仅当路径含 "op_kernel" 子串时归入 kernel_files 并传给 check_header_reachability;rglob 收集 .cpp/.h/.hpp 后按 "build_out"/"pregen" 子串排除。read_lines 以 encoding="utf-8", errors="replace" 读取,解码失败字节被替换而非抛错。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py:L47–L48](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py#L47-L48), [jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py:L264–L264](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py#L264-L264), [jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py:L271–L283](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py#L271-L283) + + + + + +**括号 depth<0 或文件末尾 depth≠0 各记一条 ERROR 并可定位到行号** +check_brace_balance 在剥离注释/字符串后统计深度:depth<0 时 error("brace depth went negative ... likely extra '}'") 并 return;遍历完 depth!=0 时在最后一行报 "brace imbalance: depth=N at end of file (expected 0)"。这些 error 使 result.ok 为 False,main 打印 FAILED 并 sys.exit(1)。CheckResult.ok 定义为 errors 列表为空。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py:L64–L73](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py#L64-L73), [jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py:L42–L44](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py#L42-L44) + + + + + +**轻量正则/计数式检查:快速且无需编译,但不做真实语法解析** +设计推断(非作者历史意图): + +(推断)收益:剥注释/字符串后按字符计数与正则匹配即可在任意算子目录快速给出带行号的错误;代价:如 #if 分支、宏展开或跨行字符串等真实预处理语义不在其能力内,注释剥离只处理 // 与双引号字符串,可能漏判或误判。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py:L55–L73](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py#L55-L73), [jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py:L76–L88](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py#L76-L88) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ascend-trace-instrumentation-planner.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ascend-trace-instrumentation-planner.md new file mode 100644 index 00000000..109112f8 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ascend-trace-instrumentation-planner.md @@ -0,0 +1,62 @@ +--- +title: "插桩计划生成器(调用图深度受限展开):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L136-L140, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L148-L159, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L27-L27, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L106-L112, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L139-L139, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L148-L149, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L59-L72, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L98-L103, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L108-L118, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L126-L130, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L1-L5, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L7-L18, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L75-L82] +feature: "ascend-trace-instrumentation-planner" +entry_points: ["jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py"] +source_globs: ["jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py"] +--- + +# 插桩计划生成器(调用图深度受限展开):实现深读 + +[功能概览](feature-ascend-trace-instrumentation-planner.md) · [owner 入口](_index.md) + + +**命令行接口:--root 与 --entry 必填,-o/--output 默认 instrumentation_plan.json** +脚本是独立 CLI(argparse):--root 指定算子源码根目录、--entry 指定入口函数名,二者 required;-o/--output 默认 "instrumentation_plan.json"。成功时写出缩进 2 的 JSON,顶层键为 root(解析后的绝对路径字符串)、entry、max_depth(固定 5)、plan;入口不存在时以非零方式 SystemExit 并输出 "entry function not found: {entry}"。调用方需保证 root 是可读目录。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L136–L140](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py#L136-L140), [jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L148–L159](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py#L148-L159) + + + + + +**展开深度由常量 MAX_DEPTH=5 固定,无命令行覆盖项** +深度上限是模块级常量 MAX_DEPTH = 5,输出 JSON 的 max_depth 字段记录该值;CLI 未提供调整参数。子节点 depth 记为 min(depth+1, MAX_DEPTH),当 depth+1 > MAX_DEPTH 时子节点标记 merged=True、merge_reason="depth_limit" 且不再入队。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L27–L27](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py#L27-L27), [jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L106–L112](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py#L106-L112), [jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L139–L139](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py#L139-L139) + + + + + +**仅依赖标准库;调用图按已提取的裸函数名匹配,未知调用名不建边** +脚本只 import argparse/json/logging/pathlib/re 及标准集合/dataclass/typing,无第三方依赖。build_call_graph 把每个函数 calls 中出现在已知函数名集合且非自调用的名字加入边;因此只有与提取到的函数名相同的调用字符串才会形成图边。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L7–L18](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py#L7-L18), [jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L75–L82](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py#L75-L82) + + + + + +**入口缺失即 SystemExit;未闭合函数体回退为剩余文本** +触发一:args.entry 不在扫描到的函数名集合时 raise SystemExit(f"entry function not found: {args.entry}"),进程终止、不写输出文件。触发二:extract_block 扫描到文本末尾仍未配平花括号时返回从开括号到文件末尾的剩余文本(含 n-1 结束索引),即解析容错而非报错。循环边由 seen_edges 的 (fn, c, depth) 三元组去重防止重复展开。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L148–L149](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py#L148-L149), [jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L59–L72](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py#L59-L72), [jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L98–L103](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py#L98-L103) + + + + + +**深度上限与 helper 合并控制计划规模,代价是深层函数与简单 helper 不再单独展开** +设计推断(非作者历史意图): + +收益(推理标注):MAX_DEPTH 与 (fn,c,depth) 去重共同限定 BFS 展开规模,保证输出有界。成本:depth+1 > MAX_DEPTH 的子节点只保留 merged 标记不再展开;is_low_value_helper 把不含 HOT_WORDS 且以 get/set/check/calc/init 开头、长度 ≤18 的函数名直接合并(merge_reason="helper_merge"),不考察其内部调用。另注:脚本头部声明不修改源文件。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L108–L118](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py#L108-L118), [jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L126–L130](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py#L126-L130), [jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L1–L5](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py#L1-L5) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ascend-trace-preprocessor.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ascend-trace-preprocessor.md new file mode 100644 index 00000000..b1ab3fcc --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ascend-trace-preprocessor.md @@ -0,0 +1,73 @@ +--- +title: "TRACE_POINT 预处理器与 point_map 映射导出:实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_preprocessor.py:L32-L43, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_preprocessor.py:L77-L85, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_preprocessor.py:L95-L106, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_preprocessor.py:L115-L135, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_preprocessor.py:L28-L28, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_preprocessor.py:L87-L93, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_preprocessor.py:L121-L135, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/patch_build_pipeline.py:L54-L59, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/apply_trace_scaffold.sh:L20-L26, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_preprocessor.py:L32-L35, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/reference.md:L337-L348] +feature: "ascend-trace-preprocessor" +entry_points: ["jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_preprocessor.py"] +source_globs: ["jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_preprocessor.py", "jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/apply_trace_scaffold.sh", "jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/patch_build_pipeline.py"] +--- + +# TRACE_POINT 预处理器与 point_map 映射导出:实现深读 + +[功能概览](feature-ascend-trace-preprocessor.md) · [owner 入口](_index.md) + + +**process_file 在 modify 模式下用 point_id 原地替换 TRACE_POINT 调用** +`process_file` 以正则匹配每个 `TRACE_POINT("标签", "类型")`,按行号排序后分配递增 point_id;当 `modify=True` 且有匹配点时,按 start 位置倒序把每处调用文本替换为数字 point_id 并回写源文件(UTF-8),随后 `save_mappings` 把 `point_map` 以 `output_dir` 相对路径写入 `point_map.json`。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_preprocessor.py:L32–L43](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_preprocessor.py#L32-L43), [jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_preprocessor.py:L77–L85](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_preprocessor.py#L77-L85), [jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_preprocessor.py:L95–L106](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_preprocessor.py#L95-L106) + + + + + +**main 接受 src、output 位置参数与可选 --modify,有匹配点时才导出映射** +CLI 契约:`src`(文件或目录)、`output`(point_map.json 输出目录)、`--modify`(store_true,替换源文件中的 TRACE_POINT)。src 为文件走 `process_file`,为目录走 `process_directory`;仅当返回的匹配点列表非空时调用 `save_mappings`,因此无 TRACE_POINT 时不会生成映射文件。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_preprocessor.py:L115–L135](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_preprocessor.py#L115-L135) + + + + + +**modify 默认关闭,--modify 开启源码改写;仅当发现点时导出映射** +process_file/process_directory 的 modify 默认 False(只扫描不改写);CLI 用 --modify(store_true)开启替换。main 仅在返回的点列表非空时调用 save_mappings。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_preprocessor.py:L28–L28](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_preprocessor.py#L28-L28), [jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_preprocessor.py:L87–L93](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_preprocessor.py#L87-L93), [jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_preprocessor.py:L121–L135](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_preprocessor.py#L121-L135) + + + + + +**apply_trace_scaffold.sh 调用 patch_build_pipeline 注入 trace_preprocessor 命令** +patch_build_pipeline.inject_hook 把 --preprocessor-cmd 文本插入编译脚本(用 START/END 标记包裹);apply_trace_scaffold.sh 以占位的 trace_preprocessor.py ... --modify 命令调用它,并注明该命令需按仓库实际变量名修改。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/patch_build_pipeline.py:L54–L59](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/patch_build_pipeline.py#L54-L59), [jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/apply_trace_scaffold.sh:L20–L26](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/apply_trace_scaffold.sh#L20-L26) + + + + + +**纯正则文本匹配:无需语法解析,但只识别两个双引号参数的特定文本形式且无匹配时静默跳过** +设计推断(非作者历史意图): + +L32 的正则仅按文本形式匹配 TRACE_POINT 后两个由双引号括起的非引号字符序列;无匹配时 L34-35 直接返回 [] 且不告警。推断:收益是无需 C/C++ 语法解析即可替换打点,代价是宏生成或其它书写形式的打点会被静默漏检。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_preprocessor.py:L32–L35](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_preprocessor.py#L32-L35) + + + + + +**文档化手工流程:以 --modify 运行 trace_preprocessor.py 生成含 label/event_type/file/line/event_id 的 point_map.json(未执行)** +文档中的人工验收步骤(本轮未执行): + +reference.md 记录的手工步骤:python /scripts/trace_preprocessor.py --modify,预期输出 point_map.json,其 points 以 point_id 为键,每项含 label、event_type、file、line、event_id。此为已记录的手工流程,本次 NOT EXECUTED,未声称任何运行时或自动化测试覆盖。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/reference.md:L337–L348](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/reference.md#L337-L348) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-audit-integrity-hmac-signing.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-audit-integrity-hmac-signing.md new file mode 100644 index 00000000..1a61b693 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-audit-integrity-hmac-signing.md @@ -0,0 +1,60 @@ +--- +title: "符号审计完整性 HMAC 签名与信任验证(audit_integrity.py):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L697-L712, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L625-L635, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L654-L663, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L452-L458, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L520-L554, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L175-L180, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L466-L490, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L444-L503, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L537-L560, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L175-L176] +feature: "audit-integrity-hmac-signing" +entry_points: ["jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py"] +source_globs: ["jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py"] +--- + +# 符号审计完整性 HMAC 签名与信任验证(audit_integrity.py):实现深读 + +[功能概览](feature-audit-integrity-hmac-signing.md) · [owner 入口](_index.md) + + +**verify_agent_record:对 agent_audited 记录做签名与哈希比对并归类信任结果** +verify_or_report 遍历 audit.status == "agent_audited" 的记录调用 verify_agent_record;该函数在记录缺 integrity.signature 或缺 batch_hash 时直接返回 "invalid_agent_audit",否则比对 payload_hash 与 hmac_signature(secret, payload_hash)(hmac.compare_digest),任一 mismatch/untrusted_script_hash 置 invalid 并返回 "invalid_agent_audit"、closure_eligible=False;仅哈希类不一致(symbol/source/entry_doc_hash_changed)单独标记 stale,batch 重用超阈值标记 suspicious。这是函数返回值,不代表进程退出码。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L444–L503](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py#L444-L503), [jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L537–L560](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py#L537-L560), [jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L175–L176](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py#L175-L176) + + + + + +**main 按 command 分派,verify_or_report 在 verify 模式返回 0-4 区分退出码** +main(argv) 解析后分派 ensure-key/promote/verify/report;AuditIntegrityError 被捕获并以 JSON 打到 stderr 后 return 1。verify_or_report 在 verify_mode 下按 invalid/stale/suspicious/closure 未通过分别返回 1/2/3/4,report 模式恒 return 0。此返回值仅是函数局部返回值,不证明进程退出码。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L697–L712](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py#L697-L712), [jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L625–L635](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py#L625-L635) + + + + + +**add_repo_key_arguments:--repo-root 必填,签名密钥参数默认取常量** +解析器要求 --repo-root 与 --audit-map 必填;--signing-key-env 默认 DEFAULT_SIGNING_KEY_ENV、--key-id 默认 DEFAULT_KEY_ID、--strict 为 store_true 开关;这些默认常量的具体值不在所示行内。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L654–L663](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py#L654-L663) + + + + + +**verify_agent_record 依赖 verify_or_report 传入的 signing_secret 密钥与 hmac/hashlib 实现** +verify_or_report 通过 signing_secret(args.signing_key_env, root, args.key_id) 取得密钥(L523),并作为 secret 传入 verify_agent_record(L548–L551);该函数用 hmac_signature 以 HMAC-SHA256 计算 integrity.payload_hash 的期望签名(L487,定义见 L175–L176),并用 hmac.compare_digest 与记录中 signature 比较(L488)。同时依赖本脚本自身的 file_hash:integrity.script_hash 与 script_hash() 不一致时追加 untrusted_script_hash 并置 invalid=True(L466–L468)。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L520–L554](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py#L520-L554), [jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L175–L180](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py#L175-L180), [jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L466–L490](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py#L466-L490) + + + + + +**无签名或缺 batch_hash 的记录直接判 invalid_agent_audit** +verify_agent_record 开头两个守卫:integrity 非 dict 或无 signature 返回 ("invalid_agent_audit", ["unsigned_agent_audit","invalid_agent_audit"], False);batch 缺 batch_hash 返回 missing_agent_call_signature 分支。此类记录不计入 closure eligible。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L452–L458](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py#L452-L458) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-audit-report-html-renderer.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-audit-report-html-renderer.md new file mode 100644 index 00000000..f2b40c7c --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-audit-report-html-renderer.md @@ -0,0 +1,51 @@ +--- +title: "自包含审计可视化 HTML 报告生成器:实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L546-L555, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L42-L53, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L30-L39, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L512-L528] +feature: "audit-report-html-renderer" +entry_points: ["jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py"] +source_globs: ["jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py"] +--- + +# 自包含审计可视化 HTML 报告生成器:实现深读 + +[功能概览](feature-audit-report-html-renderer.md) · [owner 入口](_index.md) + + +**main parses argv, renders report, prints JSON output path and returns 0 locally** +main(argv) 解析参数并调用 generate_report;成功时打印 json.dumps({"output": ...}) 并 return 0。这是函数局部返回值,不是进程退出码断言。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L546–L555](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py#L546-L555) + + + + + +**generate_report reads two JSON maps and writes the HTML file itself** +generate_report(args) resolves paths, reads coverage-map.json and symbol-audit-map.json, builds the model, and writes HTML to the resolved output path (creating parent dirs) before returning that path; main prints {"output": path} JSON on success. + +来源:[jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L512–L528](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py#L512-L528), [jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L546–L555](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py#L546-L555) + + + + + +**resolve_paths falls back to artifact_root/project defaults when CLI args absent** +coverage-map.json、symbol-audit-map.json、audit-integrity-report.json 和 audit-report.html 默认位于 (artifact_root 或 repo_root/DEFAULT_ARTIFACT_ROOT)/project/ 下,显式参数优先。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L42–L53](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py#L42-L53) + + + + + +**read_json wraps missing, invalid, and non-object JSON as AuditReportError; main prints to stderr and returns 1** +FileNotFoundError、JSONDecodeError 及顶层非 dict 分别抛出带 label 与 path 的 AuditReportError;main 捕获后打印到 stderr 并 return 1(局部返回值),否则正常输出。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L30–L39](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py#L30-L39), [jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L546–L555](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py#L546-L555) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-cross-channel-history-search-skill.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-cross-channel-history-search-skill.md new file mode 100644 index 00000000..e8dc2ee8 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-cross-channel-history-search-skill.md @@ -0,0 +1,62 @@ +--- +title: "Cross-Channel Session History Search Skill:实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py:L301-L412, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py:L82-L89, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py:L304-L329, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py:L355-L367, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py:L16-L21, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/common/utils.py:L2337-L2338, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py:L142-L152, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py:L187-L189, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py:L381-L397] +feature: "cross-channel-history-search-skill" +entry_points: ["jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py"] +source_globs: ["jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py"] +--- + +# Cross-Channel Session History Search Skill:实现深读 + +[功能概览](feature-cross-channel-history-search-skill.md) · [owner 入口](_index.md) + + +**main(): parse args, resolve time window, scan sessions, optionally auto-expand, emit report** +main() parses CLI args, resolves tz (ZoneInfo(args.timezone), fallback UTC+8), builds start/end (default last 24h; --start/--end parsed, --at centered on --window-minutes), swaps if start>end, calls _search_once, and if no hits with --auto-expand and no explicit --start/--end re-runs over last 72h; then _emit_search_report and returns 0. + +来源:[jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py:L301–L412](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py#L301-L412) + + + + + +**Defaults: sessions root from jiuwenswarm or env, window 120min, timezone Asia/Shanghai, limit 20, max-sessions 200, auto-expand on** +--sessions-root default "" triggers _default_sessions_root(): get_agent_sessions_dir() when jiuwenswarm imports, else JIUWENSWARM_DATA_DIR/agent/sessions, else ~/.jiuwenswarm/agent/sessions. Defaults: --window-minutes 120, --timezone Asia/Shanghai, --limit 20, --max-sessions 200, --auto-expand True (--no-auto-expand disables); window_minutes/limit/max_sessions clamped to >=1. + +来源:[jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py:L82–L89](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py#L82-L89), [jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py:L304–L329](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py#L304-L329), [jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py:L355–L367](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py#L355-L367) + + + + + +**Optional jiuwenswarm import for sessions root; env-var and home-dir fallback** +The script tries to import get_agent_sessions_dir from jiuwenswarm.common.utils (utils.py returns get_agent_root_dir()/"sessions"); on ImportError _default_sessions_root falls back to $JIUWENSWARM_DATA_DIR/agent/sessions, else ~/.jiuwenswarm/agent/sessions. Consequence: sessions-root resolution differs by whether the package is importable. + +来源:[jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py:L16–L21](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py#L16-L21), [jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py:L82–L89](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py#L82-L89), [jiuwenswarm/common/utils.py:L2337–L2338](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/common/utils.py#L2337-L2338) + + + + + +**Unreadable or malformed history.json yields an empty record list; missing sessions root yields no dirs** +_read_history_file catches read and json.loads exceptions and returns [] (also when data is not a list), so a corrupt file contributes no hits instead of failing the run; _iter_session_dirs returns [] when sessions_root does not exist. + +来源:[jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py:L142–L152](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py#L142-L152), [jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py:L187–L189](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py#L187-L189) + + + + + +**Auto-expand retries with a fresh 72h window when the first pass finds no hits** +设计推断(非作者历史意图): + +Benefit: when auto_expand is true and neither --start nor --end was passed, a no-hit first _search_once triggers one retry over now-72h..now, improving recall without caller re-invocation. Cost (inference): the retry replaces the original window (e.g. an --at-centered one) rather than widening it, and only fires when no explicit start/end were given. + +来源:[jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py:L381–L397](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py#L381-L397) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-daily-report-skill.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-daily-report-skill.md new file mode 100644 index 00000000..5c62bea4 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-daily-report-skill.md @@ -0,0 +1,71 @@ +--- +title: "进阶版日报/周报/月报生成器 Skill:实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/generators/report_generator.py:L484-L506, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/collectors/email_collector.py:L99-L110, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/collectors/email_collector.py:L146-L158, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/generators/report_generator.py:L28-L39, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/run_report.py:L745-L762, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/generators/report_generator.py:L23-L25, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/generators/report_generator.py:L80-L92, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/generators/__init__.py:L11-L13, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/generators/report_generator.py:L86-L101, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/SKILL.md:L47-L108] +feature: "daily-report-skill" +entry_points: ["jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/generators/__init__.py", "jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/generators/report_generator.py", "jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/run_report.py"] +source_globs: ["jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/generators/__init__.py", "jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/generators/report_generator.py", "jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/run_report.py", "jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/analyzers/ai_analyzer.py", "jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/collectors/email_collector.py", "jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/collectors/git_collector.py", "jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/collectors/__init__.py", "jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/collectors/aggregator.py", "jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/report_helper.py", "jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/collectors/todo_collector.py", "jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/analyzers/work_analyzer.py"] +--- + +# 进阶版日报/周报/月报生成器 Skill:实现深读 + +[功能概览](feature-daily-report-skill.md) · [owner 入口](_index.md) + + +**main() 测试入口:校验 argv 后用 DataAggregator 生成日报并打日志** +main() 在 sys.argv 少于 2 时打印 Usage 并 sys.exit(1);否则以 argv[1] 为 workspace_dir(可选 argv[2] 为 git_repo)构造 DataAggregator 与 ReportGenerator,调用 generate_daily() 并用 logging.info 输出日报文本。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/generators/report_generator.py:L484–L506](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/generators/report_generator.py#L484-L506) + + + + + +**EmailCollector.connect() 返回 bool 表示 IMAP 连接+登录是否成功** +connect() 在 try 内建立 imaplib.IMAP4_SSL(self.imap_server, 993) 并 login(email_address, auth_code),成功返回 True;构造函数要求 provider 属于 NETEASE_IMAP_SERVERS,否则 raise ValueError,imaplib 不可用时 raise ImportError。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/collectors/email_collector.py:L99–L110](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/collectors/email_collector.py#L99-L110), [jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/collectors/email_collector.py:L146–L158](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/collectors/email_collector.py#L146-L158) + + + + + +**ReportConfig 默认值:AI 分析默认关闭、含趋势;run_report daily 分支默认开启 AI(除非 --no-ai)** +ReportConfig 默认 report_type="daily"、include_trends=True、enable_ai_analysis=False、ai_auto_mode=True;而 run_report.py 的 daily 分支中 enable_ai = not args.no_ai,即默认启用 AI 分析,与库层默认相反。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/generators/report_generator.py:L28–L39](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/generators/report_generator.py#L28-L39), [jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/run_report.py:L745–L762](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/run_report.py#L745-L762) + + + + + +**ReportGenerator 直接依赖 WorkAnalyzer、AIAnalyzer、DataAggregator** +report_generator.py 通过相对导入引入 AnalysisResult/WorkAnalyzer、AIAnalyzer/AIAnalysisResult、CollectedData/DataAggregator,generate_daily 内调用 data_aggregator.collect 与 work_analyzer.analyze;generators/__init__.py 仅再导出 ReportGenerator 与 ReportConfig。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/generators/report_generator.py:L23–L25](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/generators/report_generator.py#L23-L25), [jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/generators/report_generator.py:L80–L92](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/generators/report_generator.py#L80-L92), [jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/generators/__init__.py:L11–L13](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/generators/__init__.py#L11-L13) + + + + + +**AIAnalyzer 初始化抛出异常时 _run_ai_analysis 记 info 日志并返回 None** +在 config.enable_ai_analysis 为真的分支中,若 self.ai_analyzer 为 None 且 AIAnalyzer() 构造抛出任意 Exception,捕获后 logging.info 记录失败信息并返回 None,ai_result 为 None 仍传入 _render_daily_report 继续渲染。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/generators/report_generator.py:L86–L101](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/generators/report_generator.py#L86-L101) + + + + + +**SKILL.md 记录的 run_report.py daily/weekly/monthly --save 手动命令(未执行)** +文档中的人工验收步骤(本轮未执行): + +SKILL.md 明确要求用 bash 执行 `python ~/.jiuwenswarm/agent/workspace/skills/advanced-daily-report/run_report.py daily --save`(含 --date、weekly、monthly 变体),并描述脚本自动采集 Git/邮件/记忆/待办后生成报告。这是文档化的手动流程与预期结果,本文未执行;所示片段不含该 Skill 的自动化测试断言。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/SKILL.md:L47–L108](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/SKILL.md#L47-L108) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-deepsearch-research-pipeline.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-deepsearch-research-pipeline.md new file mode 100644 index 00000000..87febaab --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-deepsearch-research-pipeline.md @@ -0,0 +1,82 @@ +--- +title: "openJiuwen-DeepSearch 深度研究执行管线:实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py:L200-L230, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py:L80-L98, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py:L41-L46, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py:L147-L161, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py:L6-L34, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py:L152-L161, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py:L225-L230, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py:L233-L235, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/SKILL.md:L12-L16] +feature: "deepsearch-research-pipeline" +entry_points: ["jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py"] +source_globs: ["jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py", "jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/validate_environment.py", "jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/convert_docx.py", "jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/convert_html.py", "jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/verify_skill_structure.py"] +--- + +# openJiuwen-DeepSearch 深度研究执行管线:实现深读 + +[功能概览](feature-deepsearch-research-pipeline.md) · [owner 入口](_index.md) + + +**execute_deep_search 同步封装异步工作流并返回报告或 None** +execute_deep_search(query) 先调用 load_agent_config() 加载配置,再用 asyncio.run(run_jiuwen_workflow(query, agent_config)) 执行工作流;结果非空则返回报告字符串,为空时记录 warning 并返回 None。run_jiuwen_workflow 内部通过 AgentFactory 创建 agent,异步消费 agent.run 的 chunk 流,用 parse_endnode_content 提取最终报告。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py:L200–L230](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py#L200-L230), [jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py:L80–L98](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py#L80-L98) + + + + + +**execute_deep_search(query) 返回报告字符串,捕获 ValueError 与 Exception 时返回 None** +execute_deep_search 接收研究题目 query,加载配置后用 asyncio.run 执行 run_jiuwen_workflow;结果非空则返回该字符串,为空记 warning 返回 None,ValueError 与 Exception 分支记日志后同样返回 None(不覆盖 BaseException)。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py:L200–L230](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py#L200-L230) + + + + + +**SKILL_ROOT 环境变量默认脚本上级目录,.env 仅为推荐配置位置** +SKILL_ROOT 取环境变量,未设置时默认 Path(__file__).parent.parent,并 load_dotenv(SKILL_ROOT/.env)。load_agent_config 用 os.getenv 检查进程环境中必需变量(含 WEB_SEARCH_API_KEY/WEB_SEARCH_URL),缺失时抛出列出变量名的 ValueError,提示语仅建议写入 .env 文件。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py:L41–L46](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py#L41-L46), [jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py:L147–L161](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py#L147-L161) + + + + + +**管线依赖 openjiuwen-deepsearch==0.1.1 并直接导入其 Config/AgentFactory/LogManager** +模块 docstring 声明依赖 openjiuwen-deepsearch==0.1.1 与 python-dotenv;源码实际 from openjiuwen_deepsearch 导入 Config、ExecutionMethod、AgentFactory、ResultExporter、parse_endnode_content、LogManager,并从本地 convert_docx/convert_html 导入转换函数,构成对 SDK 与本地脚本的硬耦合。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py:L6–L34](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py#L6-L34) + + + + + +**缺环境变量抛 ValueError,execute_deep_search 捕获后返回 None** +触发条件:任一必填环境变量为空,load_agent_config 在 guard `if missing_vars:` 中 raise ValueError;execute_deep_search 的 `except ValueError`/`except Exception` 分支记录日志并 return None,异常不向外传播,仅以 None 结果呈现。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py:L152–L161](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py#L152-L161), [jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py:L225–L230](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py#L225-L230) + + + + + +**execute_deep_search 吞掉 ValueError/Exception 便于调用方,但错误细节只在日志中** +设计推断(非作者历史意图): + +益处:Agent 调用方拿到的失败结果统一为 None,不会因配置缺失(ValueError)或其他 Exception 中断。代价:异常的具体原因仅写入 logger.error/exception,调用方无法从返回值区分失败原因(推断)。另 run_background 以注释说明其检查用于防止后台自我重启的无限循环。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py:L225–L230](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py#L225-L230), [jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py:L233–L235](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py#L233-L235) + + + + + +**SKILL.md 记录的手动验收流程(仅环境预检与启动观察,未执行)** +文档中的人工验收步骤(本轮未执行): + +文档化手动流程(NOT EXECUTED):先确认技能目录存在 .venv 与已填写的 .env(占位值不算),再运行 uv run "scripts\main.py" --mode query --query "<标题>",随后读取技能文件夹根目录 PID.info 中的后台子进程 PID,等待约15分钟,并通过该 PID 进程与技能文件夹中的 Markdown/Doc/Html 文件列表判断报告是否生成完成。仅覆盖预检与启动/观察步骤,未含报告内容的断言。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/SKILL.md:L12–L16](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/SKILL.md#L12-L16) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-docx-pro-cli.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-docx-pro-cli.md new file mode 100644 index 00000000..97a9d020 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-docx-pro-cli.md @@ -0,0 +1,64 @@ +--- +title: "docx-pro Word 文档操作 CLI:实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/docx_pro.py:L404-L421, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/docx_replace.py:L212-L236, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/setup_check.py:L9-L26, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/docx_pro.py:L31-L31, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/docx_pro.py:L174-L179, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/docx_pro.py:L414-L421, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/docx_pro.py:L424-L425] +feature: "docx-pro-cli" +entry_points: ["jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/docx_pro.py", "jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/setup_check.py"] +source_globs: ["jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/docx_pro.py", "jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/setup_check.py", "jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/docx_replace.py", "jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/renderer.py", "jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/md_export.py"] +--- + +# docx-pro Word 文档操作 CLI:实现深读 + +[功能概览](feature-docx-pro-cli.md) · [owner 入口](_index.md) + + +**main 解析参数并按存在性检查后分发到 args.func 的局部返回** +main 先对 json/md/docx/map 中非空且非 "-" 的路径做存在性检查(缺失则记录并返回 2),否则返回 args.func(args);分发函数抛 FileNotFoundError/ValueError 时同样记录并返回 2。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/docx_pro.py:L404–L421](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/docx_pro.py#L404-L421) + + + + + +**replace_in_docx 的 options 默认值:scope=all、case_sensitive=True、verify=True** +options.get 取默认 scope="all"、case_sensitive=True、dry_run=False、verify=True;scope="body" 时 _target_parts 只保留 REPLACE_BODY_PARTS 内的部件,否则按白名单加 .xml 前缀扩展。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/docx_replace.py:L212–L236](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/docx_replace.py#L212-L236) + + + + + +**docx-pro 脚本依赖 python-docx 并提供 setup_check 自检** +设计推断(非作者历史意图): + +setup_check.check 尝试 import docx 与 docx.shared,ImportError/异常时返回 False;docx_pro.py 将脚本目录加入 sys.path(推断:便于导入同目录模块)。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/setup_check.py:L9–L26](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/setup_check.py#L9-L26), [jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/docx_pro.py:L31–L31](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/docx_pro.py#L31-L31) + + + + + +**cmd_replace 对同路径覆盖返回 2,main 捕获两类异常返回 2** +输出文件绝对路径等于输入时报 "输出文件不得覆盖输入文件" 并返回 2;main 捕获 FileNotFoundError/ValueError 记录 "[错误]" 后返回 2。返回值是局部返回,非进程退出码证明。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/docx_pro.py:L174–L179](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/docx_pro.py#L174-L179), [jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/docx_pro.py:L414–L421](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/docx_pro.py#L414-L421) + + + + + +**main 仅捕获分发调用的 FileNotFoundError/ValueError 并返回 2:统一局部返回码,代价是仅凭返回值无法区分错误类型** +设计推断(非作者历史意图): + +main 对 args.func(args) 的返回值原样透传,并仅将 FileNotFoundError 与 ValueError 两类异常记录 '[错误]' 后返回 2。收益是这两类常见错误有统一的局部返回值 2;成本是调用方仅凭该返回值无法区分是缺文件还是非法参数,且其他类型异常不在捕获之列(推断)。此为函数返回值,不构成进程退出码证明(尽管 __main__ 下 sys.exit(main()) 会传递它)。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/docx_pro.py:L404–L421](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/docx_pro.py#L404-L421), [jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/docx_pro.py:L424–L425](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/docx_pro.py#L424-L425) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-financial-document-parser.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-financial-document-parser.md new file mode 100644 index 00000000..200765b2 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-financial-document-parser.md @@ -0,0 +1,71 @@ +--- +title: "财务文档解析 Skill(发票/收据/对账单解析与报告生成):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/financial_parser.py:L82-L103, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/financial_parser.py:L507-L554, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/financial_parser.py:L521-L525, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/financial_parser.py:L421-L425, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/financial_parser.py:L17-L29, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/financial_parser.py:L105-L108, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/financial_parser.py:L135-L158, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/financial_parser.py:L135-L153, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/financial_parser.py:L532-L554, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/financial_parser.py:L135-L148] +feature: "financial-document-parser" +entry_points: ["jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/financial_parser.py"] +source_globs: ["jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/financial_parser.py"] +--- + +# 财务文档解析 Skill(发票/收据/对账单解析与报告生成):实现深读 + +[功能概览](feature-financial-document-parser.md) · [owner 入口](_index.md) + + +**FinancialParser.parse: dispatch by file suffix, then post-process and return self.doc** +parse() 先检查文件存在,再按后缀分发:.pdf→_parse_pdf,.png/.jpg/.jpeg→_parse_image,.csv→_parse_csv,其余抛 ValueError;之后依次执行 _detect_doc_type/_categorize_items/_generate_insights 并返回 self.doc。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/financial_parser.py:L82–L103](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/financial_parser.py#L82-L103) + + + + + +**main 的 CLI 契约:--format 默认 markdown,csv 导出提示受 --quiet 守卫,异常打印 stderr 并 sys.exit(1)** +main 接受位置参数 file 与 --format(choices markdown/json/csv/all,默认 markdown)。json/all 分支向 stdout 打印结果;csv 分支调用 to_csv(args.output),仅当未传 --quiet 时才向 stderr 打印「已导出到」路径。try 块(532–550)内的任何 Exception 被捕获,打印「错误: {e}」到 stderr 后 sys.exit(1);argparse 解析(527)不在此守卫内。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/financial_parser.py:L507–L554](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/financial_parser.py#L507-L554) + + + + + +**--format 默认 markdown;to_csv 无 output 时回退为输入文件同目录 .csv 后缀** +--format/-f 的 choices 为 markdown/json/csv/all,默认 'markdown';--output 仅用于 csv。to_csv(output_path=None) 时 final_path 取 self.file_path.with_suffix('.csv')。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/financial_parser.py:L521–L525](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/financial_parser.py#L521-L525), [jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/financial_parser.py:L421–L425](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/financial_parser.py#L421-L425) + + + + + +**pdfplumber 与 pdf2image/pytesseract 为 try/except ImportError 探测的可选依赖,缺失时 PDF 抛错、图片抛错、_ocr_pdf 静默返回** +模块导入处用 try/except ImportError 设置 HAS_PDFPLUMBER/HAS_OCR 标志。_parse_pdf 在无 pdfplumber 时抛 ImportError(提示 pip install pdfplumber);_parse_image 在无 OCR 依赖时抛 ImportError;_ocr_pdf 在无 OCR 依赖时直接 return,不写 raw_text。OCR 语言固定为 chi_sim+eng(140–144 行的 PDF 路径与 157 行的图片路径均可见)。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/financial_parser.py:L17–L29](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/financial_parser.py#L17-L29), [jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/financial_parser.py:L105–L108](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/financial_parser.py#L105-L108), [jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/financial_parser.py:L135–L158](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/financial_parser.py#L135-L158) + + + + + +**缺 OCR 依赖时 _parse_image 抛 ImportError,而 _ocr_pdf 静默返回** +_parse_image 在 HAS_OCR 为 False 时抛 ImportError('需要安装 OCR 依赖: pip install pdf2image pytesseract');_ocr_pdf 在同一守卫下直接 return,不报错也不填充 raw_text。main 捕获异常后以退出码 1 终止进程。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/financial_parser.py:L135–L153](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/financial_parser.py#L135-L153), [jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/financial_parser.py:L532–L554](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/financial_parser.py#L532-L554) + + + + + +**_ocr_pdf 在 HAS_OCR 为假时静默返回:本函数不崩溃,但也跳过 OCR 文本提取** +设计推断(非作者历史意图): + +在 _ocr_pdf 内部,HAS_OCR 为假时函数直接 return,不执行 convert_from_path、raw_text 赋值或 _extract_fields_from_text;好处是缺少 OCR 依赖时本函数不抛异常,代价是本函数内对扫描内容的文本提取被静默跳过(调用方后果未在所示行中体现)。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/financial_parser.py:L135–L148](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/financial_parser.py#L135-L148) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-github-issue-feedback-script.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-github-issue-feedback-script.md new file mode 100644 index 00000000..909fcdac --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-github-issue-feedback-script.md @@ -0,0 +1,71 @@ +--- +title: "GitHub Issue 反馈创建脚本:实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/gitcode-api/scripts/open_github_issue.py:L18-L32, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/gitcode-api/scripts/open_github_issue.py:L54-L55, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/gitcode-api/scripts/open_github_issue.py:L11-L13, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/gitcode-api/scripts/open_github_issue.py:L29-L37, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/gitcode-api/scripts/open_github_issue.py:L9-L13, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/gitcode-api/scripts/open_github_issue.py:L48-L51, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/gitcode-api/scripts/open_github_issue.py:L34-L37, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/gitcode-api/scripts/open_github_issue.py:L31-L37, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/gitcode-api/scripts/open_github_issue.py:L15-L15, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/gitcode-api/scripts/open_github_issue.py:L18-L37, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/gitcode-api/scripts/open_github_issue.py:L39-L51] +feature: "github-issue-feedback-script" +entry_points: ["jiuwenswarm/resources/agent/workspace/skills/gitcode-api/scripts/open_github_issue.py"] +source_globs: ["jiuwenswarm/resources/agent/workspace/skills/gitcode-api/scripts/open_github_issue.py"] +--- + +# GitHub Issue 反馈创建脚本:实现深读 + +[功能概览](feature-github-issue-feedback-script.md) · [owner 入口](_index.md) + + +**main 完成 path:token 解析守卫通过后构造 GitHub 客户端并调用 issues.create,打印 parsed_data 并返回 0** +main(argv) 先 argparse 解析 title 与必需的 --body;token 取 os.getenv("GITHUB_ACCESS_TOKEN") 否则回退 args.api_key(L34)。若 token 为空,经 output_content(L15 定义为 partial(print))向 stderr 输出 "GITHUB_ACCESS_TOKEN is not set" 并局部返回 1,不发起 API 调用(L35–L37)。否则组装 owner/repo/title/body,且仅当 --label 提供时加入 labels 列表(L39–L46),以 GitHub(auth=token) 调用 gh.rest(version=API_VERSION).issues.create(**payload)(L48–L49),随后 output_content(resp.parsed_data) 打印解析结果并返回 0(L50–L51)。返回 1/0 是函数局部返回值;L49 若抛出异常,所示 main 体内无 except,将向上传播。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/gitcode-api/scripts/open_github_issue.py:L15–L15](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/gitcode-api/scripts/open_github_issue.py#L15-L15), [jiuwenswarm/resources/agent/workspace/skills/gitcode-api/scripts/open_github_issue.py:L18–L37](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/gitcode-api/scripts/open_github_issue.py#L18-L37), [jiuwenswarm/resources/agent/workspace/skills/gitcode-api/scripts/open_github_issue.py:L39–L51](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/gitcode-api/scripts/open_github_issue.py#L39-L51) + + + + + +**CLI 契约:位置参数 title,--body 必填,--label 可重复,返回进程内 int** +调用方须提供位置参数 title 和必填 --body;--label 每次 append 可重复;--owner 默认 "Trenza1ore"、--repo 默认 "GitCode-API"、--api-key 默认空。main 返回 int(0 成功、1 缺 token),作为模块运行时经 raise SystemExit(main()) 转为退出码。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/gitcode-api/scripts/open_github_issue.py:L18–L32](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/gitcode-api/scripts/open_github_issue.py#L18-L32), [jiuwenswarm/resources/agent/workspace/skills/gitcode-api/scripts/open_github_issue.py:L54–L55](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/gitcode-api/scripts/open_github_issue.py#L54-L55) + + + + + +**token 优先取环境变量 GITHUB_ACCESS_TOKEN,其次 --api-key** +token = os.getenv("GITHUB_ACCESS_TOKEN") or args.api_key;owner/repo 默认常量 DEFAULT_OWNER="Trenza1ore"、DEFAULT_REPO="GitCode-API",可被同名 CLI 参数覆盖。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/gitcode-api/scripts/open_github_issue.py:L11–L13](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/gitcode-api/scripts/open_github_issue.py#L11-L13), [jiuwenswarm/resources/agent/workspace/skills/gitcode-api/scripts/open_github_issue.py:L29–L37](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/gitcode-api/scripts/open_github_issue.py#L29-L37) + + + + + +**依赖 githubkit.GitHub 执行创建,pin 到 rest version "2026-03-10"** +脚本导入 githubkit 的 GitHub 客户端并固定 API_VERSION="2026-03-10" 调用 issues.create;创建结果依赖 githubkit 的解析(resp.parsed_data)。此依赖未安装时脚本无法运行。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/gitcode-api/scripts/open_github_issue.py:L9–L13](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/gitcode-api/scripts/open_github_issue.py#L9-L13), [jiuwenswarm/resources/agent/workspace/skills/gitcode-api/scripts/open_github_issue.py:L48–L51](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/gitcode-api/scripts/open_github_issue.py#L48-L51) + + + + + +**token 为空时向 output_content 传 stderr 并返回 1;API 异常未捕获** +当 GITHUB_ACCESS_TOKEN 未设置且 --api-key 为空(falsy)时,L34–L37 以参数 file=sys.stderr 调用 output_content("GITHUB_ACCESS_TOKEN is not set") 并 return 1,不发起 API 调用。L48–L49 无 try/except,githubkit 抛出的异常会从 main 原样传播。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/gitcode-api/scripts/open_github_issue.py:L34–L37](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/gitcode-api/scripts/open_github_issue.py#L34-L37), [jiuwenswarm/resources/agent/workspace/skills/gitcode-api/scripts/open_github_issue.py:L48–L51](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/gitcode-api/scripts/open_github_issue.py#L48-L51) + + + + + +**环境变量优先于 --api-key:便于无人值守,但非空的旧值会覆盖 CLI 传入 token** +设计推断(非作者历史意图): + +L34 用 os.getenv("GITHUB_ACCESS_TOKEN") or args.api_key:环境变量非空时总是胜出,--api-key 仅在环境变量为空/falsy 时生效(推断:这便于脚本化无人值守运行,但代价是环境中残留的非空 token 会覆盖调用方在命令行显式传入的 --api-key)。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/gitcode-api/scripts/open_github_issue.py:L31–L37](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/gitcode-api/scripts/open_github_issue.py#L31-L37) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-huawei-maas-apikey-creation.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-huawei-maas-apikey-creation.md new file mode 100644 index 00000000..4ddb86c3 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-huawei-maas-apikey-creation.md @@ -0,0 +1,62 @@ +--- +title: "华为云 MaaS API Key 自动创建与捕获(auto_create_apikey):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py:L380-L406, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py:L380-L397, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py:L234-L260, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py:L371-L377, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py:L353-L370, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/lib/huawei_selectors.py:L459-L467, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py:L363-L370] +feature: "huawei-maas-apikey-creation" +entry_points: ["jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py"] +source_globs: ["jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py", "jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/lib/huawei_selectors.py"] +--- + +# 华为云 MaaS API Key 自动创建与捕获(auto_create_apikey):实现深读 + +[功能概览](feature-huawei-maas-apikey-creation.md) · [owner 入口](_index.md) + + +**main 解析参数后连接 CDP 浏览器并逐步创建、捕获 Key** +main 解析 --cdp-url/--tag/--description/--timeout/--json;cdp_url 为空时回退 resolve_cdp_url(),仍为空则输出失败 JSON 并 return 1。否则调用 auto_create_apikey 并 output_json(result),按 result.get("ok") 返回 0 或 1(main 的返回值,非本片段可证的进程退出码)。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py:L380–L406](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py#L380-L406) + + + + + +**main 的 CLI 契约:--tag 默认 jiuwenswarm、--cdp-url 空时回退 resolve_cdp_url(),按 ok 返回 0/1** +main 接受 --cdp-url(默认空)、--tag(默认 "jiuwenswarm")、--description(默认 "jiuwenswarm-config")、--timeout(默认 30 秒)与 --json 标志;cdp_url 为空时调用 resolve_cdp_url() 解析,仍无则输出 make_failure("init", "未找到 CDP URL") 并 return 1。成功路径 auto_create_apikey 返回 make_success("apikey", ..., api_key, tag, description, dialog_closed),main 输出 JSON 并 return 0 if result.get("ok") else 1。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py:L380–L406](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py#L380-L406), [jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py:L363–L370](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py#L363-L370) + + + + + +**CLI 默认值:tag=jiuwenswarm、description=jiuwenswarm-config、timeout=30 秒** +argparse 定义 --cdp-url 默认空串(空时回退 resolve_cdp_url())、--tag 默认 "jiuwenswarm"、--description 默认 "jiuwenswarm-config"、--timeout 默认 30(单步超时秒数)、--json 布尔开关。这些是本函数内的参数默认值,未在片段中显示更外层配置优先级。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py:L380–L397](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py#L380-L397) + + + + + +**连接/导航/按钮缺失各自短路为结构化失败,异常统一兜底** +connect_page 抛异常时 return make_failure("connect_failed", …);goto 失败 return make_failure("navigate_failed", …);创建按钮 15s 内未找到则带 page_url 与 page_text_preview 返回 make_failure("create_btn_not_found", …);步骤中任意未预期异常被外层 except 捕获返回 make_failure("exception", …),finally 中 best-effort pw.stop()。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py:L234–L260](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py#L234-L260), [jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py:L371–L377](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py#L371-L377) + + + + + +**复制按钮 best-effort:不阻塞成功路径,但复制可能静默失败** +设计推断(非作者历史意图): + +成功捕获 Key 后 click_copy_key_button(page) 在 huawei_selectors 中 try 内 3s 等待可见并点击,任何异常返回 False;主流程仅 emit 记录,仍继续返回 make_success(dialog_closed 单独记录)。推断:收益是复制失败不影响 Key 捕获结果,代价是用户剪贴板可能没有该 Key 而流程不报错。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py:L353–L370](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py#L353-L370), [jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/lib/huawei_selectors.py:L459–L467](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/lib/huawei_selectors.py#L459-L467) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-huawei-maas-cdp-authorize.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-huawei-maas-cdp-authorize.md new file mode 100644 index 00000000..4d32950e --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-huawei-maas-cdp-authorize.md @@ -0,0 +1,71 @@ +--- +title: "华为云 MaaS 委托授权自动化(auto_authorize):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py:L98-L133, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py:L135-L205, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py:L215-L234, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py:L98-L104, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/lib/cdp_client.py:L195-L228, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py:L100-L104, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py:L68-L95, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py:L114-L124, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py:L215-L230, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py:L98-L112, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py:L135-L176, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py:L179-L212, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/lib/flow_state.py:L9-L17] +feature: "huawei-maas-cdp-authorize" +entry_points: ["jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py"] +source_globs: ["jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py"] +--- + +# 华为云 MaaS 委托授权自动化(auto_authorize):实现深读 + +[功能概览](feature-huawei-maas-cdp-authorize.md) · [owner 入口](_index.md) + + +**auto_authorize 连接 CDP 后按固定步骤检测并完成授权** +auto_authorize 经 connect_page 连接浏览器(timeout_ms=15_000),page.goto 导航到 MAAS_HOMEPAGE_URL(timeout=30_000),sleep 2.5s 等 SPA 渲染并 handle_disclaimer;若 _detect_auth_warning 为假则直接 make_success(auth_done=False, skipped_reason="no_warning"),否则点击"此处"链接(缺失/失败时兜底点警告元素本身),等待授权对话框与"确定"按钮,最后等待成功提示并 make_success(auth_done=True)。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py:L98–L133](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py#L98-L133), [jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py:L135–L205](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py#L135-L205) + + + + + +**main(argv) CLI 契约:--cdp-url/--timeout/--json,返回 0/1** +main 解析 --cdp-url(默认空)、--timeout(默认 45)、--json;cdp_url 为空时回退 resolve_cdp_url(),仍为空则 output_json(make_failure("init", "未找到 CDP URL")) 并返回 1;否则 auto_authorize 后 output_json(result),按 result.get("ok") 返回 0 或 1(函数返回值,非进程退出码的直接证明)。auto_authorize(cdp_url, timeout_s=45) 对调用者返回结果 dict。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py:L215–L234](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py#L215-L234), [jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py:L98–L104](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py#L98-L104) + + + + + +**main 的 --cdp-url 默认为空并回退 resolve_cdp_url,--timeout 默认 45 作为 auto_authorize 的 timeout_s** +--cdp-url 缺省为空字符串,strip 后为空则调用 resolve_cdp_url() 解析;仍为空时输出 make_failure("init") 且 main 局部返回 1。--timeout 缺省 45,以 timeout_s 传入 auto_authorize;连接超时为固定 15_000ms,页内各等待用的是固定毫秒值。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py:L215–L230](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py#L215-L230), [jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py:L98–L104](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py#L98-L104) + + + + + +**惰性导入 playwright 并经 connect_over_cdp 复用首个 context 的已有 page** +import_playwright 惰性导入 playwright.sync_api,ImportError 时抛 RuntimeError 附安装指引(不需 playwright install)。connect_page 用 chromium.connect_over_cdp 连接,无 context 时抛 RuntimeError;默认 new_page=False 复用 context.pages[0],无 page 才新建,并 set_default_timeout(timeout_ms)。auto_authorize 以默认 new_page=False 调用,故操作复用浏览器默认 context 的现有 page。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/lib/cdp_client.py:L195–L228](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/lib/cdp_client.py#L195-L228), [jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py:L100–L104](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py#L100-L104) + + + + + +**auto_authorize 各失败分支返回 make_failure 载荷而非抛出,finally 中 pw.stop 异常被吞掉** +在 auto_authorize 局部分支中,连接失败返回 stage="connect_failed"、导航失败 "navigate_failed"、对话框 10s 未现为 "dialog_timeout"、确定按钮未点为 "confirm_not_found"、成功提示 15s 未现为 "success_timeout"、其余异常为 "exception";均经 make_failure 构造 dict 返回。finally 里 pw.stop() 失败仅 debug 日志。注意:'此处'点击失败且兜底 warning 为 None 时不返回,继续等待对话框。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py:L98–L112](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py#L98-L112), [jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py:L135–L176](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py#L135-L176), [jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py:L179–L212](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py#L179-L212), [jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/lib/flow_state.py:L9–L17](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/lib/flow_state.py#L9-L17) + + + + + +**两级检测 + 固定 sleep 换取稳态判定** +设计推断(非作者历史意图): + +(推断)_detect_auth_warning 先查 #authGlobalMessage 容器、容器缺失/不可见时退化为警告选择器快照并按关键词匹配,容错 DOM 变化但可能误判(如 inner_text 异常时直接返回 True,85-92 行);授权流程多处固定 time.sleep(2.5/1.5/1.0) 等 SPA 渲染与动画,稳定性换来了最坏情况下不必要的等待时长。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py:L68–L95](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py#L68-L95), [jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py:L114–L124](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py#L114-L124) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-huawei-realname-account-check.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-huawei-realname-account-check.md new file mode 100644 index 00000000..4020e8f2 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-huawei-realname-account-check.md @@ -0,0 +1,73 @@ +--- +title: "华为云账号实名认证状态检测(check_account):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/check_account.py:L50-L58, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/check_account.py:L110-L128, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/check_account.py:L111-L126, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/check_account.py:L56-L82, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/check_account.py:L57-L64, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/check_account.py:L97-L107, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/lib/huawei_selectors.py:L602-L605, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/lib/huawei_selectors.py:L561-L565, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/lib/cdp_client.py:L195-L228, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/check_account.py:L35-L47, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/SKILL.md:L193-L227] +feature: "huawei-realname-account-check" +entry_points: ["jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/check_account.py", "jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/lib/huawei_selectors.py"] +source_globs: ["jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/check_account.py", "jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/lib/huawei_selectors.py"] +--- + +# 华为云账号实名认证状态检测(check_account):实现深读 + +[功能概览](feature-huawei-realname-account-check.md) · [owner 入口](_index.md) + + +**check_account(cdp_url, timeout_s=15) 返回结果 dict;CLI 以退出码表达 ok** +函数签名 check_account(cdp_url: str, timeout_s: int = 15) -> dict,成功返回 make_success 附 realname_authenticated/popups_closed/realname_auth_url;main 接受 --cdp-url/--timeout/--json,cdp_url 为空时自动 resolve_cdp_url(),仍为空则输出失败 JSON 并返回 1,否则返回 0 当且仅当 result.get("ok")。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/check_account.py:L50–L58](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/check_account.py#L50-L58), [jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/check_account.py:L110–L128](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/check_account.py#L110-L128) + + + + + +**CLI 默认 --cdp-url 为空自动解析、--timeout 默认 15 秒** +argparse 定义 --cdp-url 默认空串(空则调 resolve_cdp_url() 自动解析)与 --timeout 默认 15;check_account 内部另将连接超时固定为 connect_page(timeout_ms=15_000)、检测超时固定为 8_000ms,不随 --timeout 改变。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/check_account.py:L111–L126](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/check_account.py#L111-L126), [jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/check_account.py:L56–L82](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/check_account.py#L56-L82) + + + + + +**check_account depends on Playwright over CDP reusing the first context's existing page, with a new-page fallback; playwright must be pip-installed** +connect_page lazily imports playwright.sync_api (raising RuntimeError with an install hint if missing), connects via chromium.connect_over_cdp, raises if browser.contexts is empty, takes contexts[0] and reuses pages[0] when present else creates a page, and sets page.set_default_timeout(timeout_ms). check_account also depends on lib.huawei_selectors (dismiss_popups, detect_realname_status, HUAWEI_REALNAME_AUTH_URL) and lib.flow_state result builders. + +来源:[jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/lib/cdp_client.py:L195–L228](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/lib/cdp_client.py#L195-L228), [jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/check_account.py:L35–L47](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/check_account.py#L35-L47) + + + + + +**连接失败与检测异常均转为 {ok:false} 返回,不抛给上层** +connect_page 抛异常时返回 make_failure("connect_failed", ...);检测阶段任何 Exception 返回 make_failure("exception", ...);detect_realname_status 在 timeout_ms 内两级探测都无果时 emit 超时消息并返回 False(视为未认证兜底);finally 中 pw.stop() 失败仅记 debug 日志。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/check_account.py:L57–L64](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/check_account.py#L57-L64), [jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/check_account.py:L97–L107](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/check_account.py#L97-L107), [jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/lib/huawei_selectors.py:L602–L605](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/lib/huawei_selectors.py#L602-L605) + + + + + +**JS 变量优先+DOM 兜底的检测换取稳定性,超时兜底偏向未认证** +设计推断(非作者历史意图): + +(推断)detect_realname_status 优先读 window.myRoleTags(不受文案/DOM 变化影响),DOM 提醒条作兜底,提高容错;代价是两级探测都未就绪时超时返回 False,即把未知状态判为未实名,可能产生误报。固定 sleep 2.0s + 弹窗关闭 sleep 也增加总时长。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/lib/huawei_selectors.py:L561–L565](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/lib/huawei_selectors.py#L561-L565), [jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/lib/huawei_selectors.py:L602–L605](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/lib/huawei_selectors.py#L602-L605) + + + + + +**SKILL.md documents running check_account.py --json --cdp-url with expected JSON for both realname outcomes (documented procedure, NOT EXECUTED here)** +文档中的人工验收步骤(本轮未执行): + +SKILL.md step 2 gives the exact command `python /scripts/check_account.py --json --cdp-url ""` and expected outputs: {"ok": true, "stage": "check_account", "realname_authenticated": true|false, "popups_closed": 1, "realname_auth_url": ...}. This is a documented manual procedure only; no automated test evidence for this feature is supplied, and nothing was executed in this batch. + +来源:[jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/SKILL.md:L193–L227](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/SKILL.md#L193-L227) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-local-doc-ocr-offline.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-local-doc-ocr-offline.md new file mode 100644 index 00000000..317b57ed --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-local-doc-ocr-offline.md @@ -0,0 +1,62 @@ +--- +title: "本地离线 OCR 管线(RapidOCR:PDF/图片 → Markdown):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/pdf_to_images.py:L74-L92, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/pdf_to_images.py:L30-L36, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py:L129-L166, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py:L22-L29, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py:L147-L155, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/write_ocr_md.py:L22-L48, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/write_ocr_md.py:L51-L72, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/setup.py:L20-L38] +feature: "local-doc-ocr-offline" +entry_points: ["jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py"] +source_globs: ["jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py", "jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/write_ocr_md.py", "jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/preprocess_img.py", "jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/pdf_to_images.py", "jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/setup.py"] +--- + +# 本地离线 OCR 管线(RapidOCR:PDF/图片 → Markdown):实现深读 + +[功能概览](feature-local-doc-ocr-offline.md) · [owner 入口](_index.md) + + +**ocr_offline.py main:解析参数 → 依赖自检 → 条件导入 RapidOCR → 构建引擎** +main() 先 argparse 解析 input/-o/-d/--no-preprocess/--start-page/--end-page/--boxes-json,调用 _ensure_deps()(返回值被忽略),随后 try 导入 rapidocr_onnxruntime.RapidOCR,导入成功则打印加载提示并构造 engine = RapidOCR();再依据 args.out 是否为空决定默认输出名(目录输入时 out_md = <目录>/_OCR.md)。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py:L129–L166](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py#L129-L166) + + + + + +**write_ocr_md.py 的 JSON 输入契约与缺省输出命名** +main() 接受 JSON 文件路径或 '-'(读 stdin),json.loads 后交给 build_md(data)。data 缺省 source 为「(未知来源)」、engine 为「多模态读图(本机模型)」、pages 为空列表;每页 label 缺省「未命名」、text 缺省空串(空文本渲染为「(本页未识别到内容)」)。未指定 -o 时按 source 同名生成 _OCR.md(stdin 时固定 ocr_OCR.md),写入后打印 DONE 行。调用方需提供可解析的 JSON。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/write_ocr_md.py:L22–L48](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/write_ocr_md.py#L22-L48), [jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/write_ocr_md.py:L51–L72](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/write_ocr_md.py#L51-L72) + + + + + +**pdf_to_images 默认 dpi=300、tiles=0,页范围由 render_one 夹紧** +argparse 默认 `-d/--dpi` 为 300、`-t/--tiles` 为 0(不切块)、`--start-page`/`--end-page` 为 None;render_one 内 `s = max(1, start_page or 1)`、`e = min(n, end_page or n)`,未指定时覆盖第 1 页到末页,输出目录默认在 PDF 同目录建 `<文件名>_pages`。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/pdf_to_images.py:L74–L92](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/pdf_to_images.py#L74-L92), [jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/pdf_to_images.py:L30–L36](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/pdf_to_images.py#L30-L36) + + + + + +**依赖自检异常仅告警返回 False;rapidocr 导入失败才 sys.exit(1)** +ocr_offline._ensure_deps 捕获任何异常后 stderr 写 [warn] 并返回 False;main() L148 调用时不接收返回值,真正的退出分支是 L150-155 的 ImportError:打印 ERROR 与 pip install -r requirements.txt 提示并 sys.exit(1)。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py:L22–L29](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py#L22-L29), [jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py:L147–L155](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py#L147-L155) + + + + + +**清华镜像优先、CalledProcessError 后无 -i 重试的安装顺序** +设计推断(非作者历史意图): + +_install_one 按 _MIRRORS 顺序尝试:先带 `-i https://pypi.tuna.tsinghua.edu.cn/simple`,仅当 subprocess.run(check=True) 抛 CalledProcessError 时换下一个源;第二个源命令不带 -i,实际来源由本机 pip 配置决定,代码不保证官方 PyPI。每次命令固定 `--retries 5 --timeout 60`。收益(推断):国内镜像通常更快;代价:首个源非退出码失败(如网络异常抛其他异常)不触发兜底,直接传播。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/setup.py:L20–L38](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/setup.py#L20-L38) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-maas-auto-open-models.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-maas-auto-open-models.md new file mode 100644 index 00000000..44b24bcb --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-maas-auto-open-models.md @@ -0,0 +1,62 @@ +--- +title: "华为云 MaaS 预置服务批量开通自动化(CDP):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L770-L812, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L772-L810, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L523-L548, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/lib/flow_state.py:L9-L17, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L808-L812, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/SKILL.md:L373-L396] +feature: "maas-auto-open-models" +entry_points: ["jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py"] +source_globs: ["jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py"] +--- + +# 华为云 MaaS 预置服务批量开通自动化(CDP):实现深读 + +[功能概览](feature-maas-auto-open-models.md) · [owner 入口](_index.md) + + +**main 解析参数后调用 auto_open_models 并按 result.ok 返回 0/1** +main 先解析 argv,cdp_url 为空时回退 resolve_cdp_url();--model 优先,否则从 --models-file 读取展示名,然后调用 auto_open_models(cdp_url, models, type_filter, timeout_s),output_json 输出结果并返回 0 if result.get("ok") else 1(此返回值是 main 的局部返回,非直接证明进程退出码)。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L770–L812](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py#L770-L812) + + + + + +**main(argv) 的 CLI 契约:可重复 --model、--models-file、--type-filter、--timeout、--json** +调用方通过 argv 传入 --cdp-url(默认空字符串)、可多次指定的 --model(优先于 --models-file)、--models-file(默认 _DEFAULT_MODELS_FILE)、--type-filter(默认 "文本生成")、--timeout(int,默认 90 秒)与 --json 开关;返回 int,成功路径取决于 result.get("ok")。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L770–L812](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py#L770-L812) + + + + + +**模型来源优先级:--model(可重复)优先,其次 --models-file;cdp-url 空则回退 resolve_cdp_url()** +args.model 非空时逐个 strip 作为模型列表;否则从 args.models_file 加载展示名。cdp_url 取 args.cdp_url 去空白,为空时调用 resolve_cdp_url()。--type-filter 默认 "文本生成"(按预置服务列表“类型”列过滤),--timeout 默认 90。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L772–L810](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py#L772-L810) + + + + + +**连接/导航/表格加载失败时返回 make_failure 统一 JSON(ok=false, stage, error),由 main 以本地返回码 1 输出** +connect_page 抛异常返回 make_failure("connect_failed");goto 抛异常或 _wait_table_ready 为假分别返回 stage=navigate_failed 与 stage=table_timeout(提示可能未登录)。make_failure 构造 {"ok": False, "stage": …, "error": …, **extra};main 输出 JSON 并按 result.get("ok") 本地 return 0/1,不证明进程退出码语义之外的行为。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L523–L548](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py#L523-L548), [jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/lib/flow_state.py:L9–L17](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/lib/flow_state.py#L9-L17), [jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L808–L812](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py#L808-L812) + + + + + +**SKILL.md 步骤 5 给出的 documented_manual 验证流程(未执行)** +文档中的人工验收步骤(本轮未执行): + +既有文档化手工流程:依次运行 navigate.py 跳转 deployment 页与 `auto_open_model.py --json --cdp-url --models-file /models.json --timeout 90`,期望 stdout 返回 ok=true、stage=open_models 且 opened/already_opened/failed 分列。此为文档记载的操作与预期结果,本轮未执行,不构成运行时证据。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/SKILL.md:L373–L396](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/SKILL.md#L373-L396) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-opc-add-slide.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-opc-add-slide.md new file mode 100644 index 00000000..bd5041a5 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-opc-add-slide.md @@ -0,0 +1,62 @@ +--- +title: "解包 PPTX 幻灯片添加工具(opc/add_slide.py):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py:L167-L186, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py:L20-L48, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py:L108-L122, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py:L177-L182, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py:L133-L163, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py:L7-L9, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py:L104-L130, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py:L167-L173, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py:L13-L18] +feature: "opc-add-slide" +entry_points: ["jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py"] +source_globs: ["jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py"] +--- + +# 解包 PPTX 幻灯片添加工具(opc/add_slide.py):实现深读 + +[功能概览](feature-opc-add-slide.md) · [owner 入口](_index.md) + + +**layout 分支:写入空幻灯片与 .rels 后登记 content type 并挂入 presentation.xml** +source 以 slideLayout 开头且该 layout 文件存在时,写入 EMPTY_SLIDE 到 ppt/slides/slideN.xml、写 .rels 指向 ../slideLayouts/{source},再调 _register_content_type 与 _register_in_presentation,返回两行摘要由 emit 输出到 stdout。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py:L104–L130](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py#L104-L130), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py:L167–L173](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py#L167-L173) + + + + + +**CLI 契约:位置参数 unpacked 与 source;结果经 emit 写 stdout** +命令行需两个位置参数:unpacked 目录与 source(slideN.xml 复制或 slideLayoutN.xml 起新页)。add_slide 返回摘要字符串,emit 经 propagate=False 的 add_slide.out logger 以裸 %(message)s 格式写 stdout,诊断走 stderr 的另一 logger。main() 捕获 AddSlideError 转为 SystemExit;main 返回值仅在 __main__ 下交给 sys.exit。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py:L167–L186](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py#L167-L186), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py:L20–L48](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py#L20-L48) + + + + + +**仅用标准库、以纯文本替换修改解包 OPC 目录中的 XML** +仅导入 logging/argparse/re/shutil/sys/pathlib,无第三方依赖;对 [Content_Types].xml、presentation.xml.rels 和 presentation.xml 做 str.replace/re.sub 文本改写,若目标标记(如 、)不存在则替换不生效且不报错。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py:L13–L18](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py#L13-L18), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py:L133–L163](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py#L133-L163) + + + + + +**AddSlideError:源布局或源幻灯片缺失时抛出,main 转为 SystemExit(消息)** +source 以 slideLayout 开头且 layouts/source 不是文件时抛 AddSlideError("add_slide: no such layout: …");否则 slides/source 不是文件时抛 "no such slide"。main() 捕获并 raise SystemExit(str(exc)),其余异常不在此处理。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py:L108–L122](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py#L108-L122), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py:L177–L182](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py#L177-L182) + + + + + +**文本替换改包结构:零依赖、可独立运行的代价是对标记字面量敏感** +设计推断(非作者历史意图): + +(推断)收益:只用标准库字符串替换即可同时改部件、.rels、[Content_Types].xml 和 presentation.xml 的 sldIdLst(注释称四处任错即被 PowerPoint 判为损坏);成本:若目标文件缺少被替换的字面闭合/包裹标记(如无 '' 且无 sldMasterIdLst 块),replace/re.sub 静默不生效,登记缺失而脚本仍返回成功摘要。sldId 取 max(used,255)+1 且下限 256 以满足编号空间要求。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py:L133–L163](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py#L133-L163), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py:L7–L9](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py#L7-L9) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-opc-pack-validate.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-opc-pack-validate.md new file mode 100644 index 00000000..dc511725 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-opc-pack-validate.md @@ -0,0 +1,82 @@ +--- +title: "OOXML 打包与 schema 校验(opc/pack.py):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/pack.py:L87-L110, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/pack.py:L147-L152, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/pack.py:L94-L102, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/repair.py:L187-L199, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/repair.py:L178-L184, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/pack.py:L101-L117, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/pack.py:L94-L126, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/pack.py:L131-L143, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/validate.py:L158-L195, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/pack.py:L62-L62, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/editing.md:L49-L95] +feature: "opc-pack-validate" +entry_points: ["jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/pack.py"] +source_globs: ["jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/pack.py", "jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/repair.py", "jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/unpack.py", "jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/validate.py"] +--- + +# OOXML 打包与 schema 校验(opc/pack.py):实现深读 + +[功能概览](feature-opc-pack-validate.md) · [owner 入口](_index.md) + + +**pack() 校验通过后在临时目录压缩 XML 并写出 ZIP** +pack() 先(默认)执行 repair_all 与 validate;若校验有错误,记录前 20 条并抛出 PackError 拒绝写出。否则把 unpacked 复制到临时目录,对每个 *.xml 与 *.rels 执行 condense,按排序且把 FIRST_ENTRY 指定的条目排最前,以 ZIP_DEFLATED 写入 output。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/pack.py:L94–L126](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/pack.py#L94-L126) + + + + + +**pack(unpacked, output, do_repair=True, do_validate=True, original=None) 前置校验与失败契约** +pack() 要求 unpacked 是目录且 output 后缀(小写比较)属于 SUPPORTED={".pptx",".docx",".xlsx"},否则抛 PackError;validation 失败时抛 PackError 拒绝写 output。main() 把 PackError 转成 SystemExit,保持函数可作库使用。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/pack.py:L87–L110](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/pack.py#L87-L110), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/pack.py:L62–L62](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/pack.py#L62-L62), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/pack.py:L147–L152](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/pack.py#L147-L152) + + + + + +**do_repair/do_validate 默认开启,--no-repair/--no-validate 关闭,--original 作为校验基线** +_run() 的 argparse 定义 `--no-repair`、`--no-validate`(store_true)与 `--original`,并以 `do_repair=not args.no_repair, do_validate=not args.no_validate` 调用 pack()。original 传入 validate 的 baseline;基线错误按 _fingerprint(去掉行号的 part+message)过滤,仅报告基线中不存在的缺陷,基线不可读时报告全部错误。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/pack.py:L131–L143](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/pack.py#L131-L143), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/validate.py:L158–L195](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/validate.py#L158-L195) + + + + + +**pack 依赖 repair.repair_all 与 validate,且 repair 会就地改写源目录** +pack 直接调用 repair_all(unpacked) 与 validate(unpacked, baseline=original)。repair_all 对每个 *.xml 逐条应用 5 条规则并当文本变化时就地 write_text,因此 do_repair=True 时传入的 unpacked 目录本身被修改,发生在 condense 的临时 staged 复制之前。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/pack.py:L94–L102](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/pack.py#L94-L102), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/repair.py:L187–L199](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/repair.py#L187-L199), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/repair.py:L178–L184](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/repair.py#L178-L184) + + + + + +**非目录/非法后缀/校验失败均抛 PackError,main() 转为 SystemExit** +unpacked 非目录或 output 后缀不在 SUPPORTED 时抛 PackError;validate 返回错误时记录前 20 条并抛 `pack: refusing to write {output}`,中止写入。main() 捕获 PackError 并 raise SystemExit(str(exc))。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/pack.py:L87–L110](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/pack.py#L87-L110), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/pack.py:L147–L152](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/pack.py#L147-L152) + + + + + +**验证失败拒写 output(安全)换取整目录复制到临时目录(成本)** +设计推断(非作者历史意图): + +收益(推断):validate 报错时 raise PackError refusing to write,output 不会被新写入的坏包覆盖。成本(推断):每次打包都要 copytree 到 TemporaryDirectory 并对全部 *.xml/*.rels 重新解析写出。注意源目录并非全程只读——repair_all 已在此之前就地改写。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/pack.py:L101–L117](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/pack.py#L101-L117) + + + + + +**editing.md 中记录的 pack.py 手动流程(未执行)** +文档中的人工验收步骤(本轮未执行): + +文档给出具体操作 `python scripts/opc/pack.py unpacked/ output.pptx --original input.pptx`,并声明其效果为校验、修复、压缩 XML、重新编码弯引号。这是 documented_manual 证据,本条未执行该流程;未见任何针对 pack.py 的自动化测试断言。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/editing.md:L49–L95](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/editing.md#L49-L95) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-plugin-package-initializer.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-plugin-package-initializer.md new file mode 100644 index 00000000..2b5bb8cf --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-plugin-package-initializer.md @@ -0,0 +1,53 @@ +--- +title: "plugin-creator 插件包脚手架初始化:实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L184-L202, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L150-L181, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L184-L206, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L129-L131, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L91-L103, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L129-L147, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L158-L162] +feature: "plugin-package-initializer" +entry_points: ["jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py"] +source_globs: ["jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py"] +--- + +# plugin-creator 插件包脚手架初始化:实现深读 + +[功能概览](feature-plugin-package-initializer.md) · [owner 入口](_index.md) + + +**main: 传入 kebab-case 名称时在 local plugin_packages 下创建含 manifest.json 与 README.md 的骨架目录** +main 校验 argv 长度后调用 resolve_init_target(sys.argv[1]),若名称匹配 NAME_RE 且 local/built_in 中均无同名目录,则 init_package 创建 pkg_dir(先 mkdir parents),写入由 MANIFEST_TEMPLATE 和 README_TEMPLATE 填充占位符得到的 manifest.json 与 README.md,通过 write_stdout 输出进度后返回 0。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L184–L202](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py#L184-L202), [jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L150–L181](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py#L150-L181) + + + + + +**接受 kebab-case 包名或显式路径参数,返回 int 状态码** +main() 在无参数时经 write_stdout 输出用法说明并 return 1;有参数时 resolve_init_target(sys.argv[1]) 接受包名或含分隔符的路径,init_package 成功后 return 0,ValueError 被捕获并把消息写到 stdout 后 return 1;脚本入口 raise SystemExit(main())。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L184–L206](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py#L184-L206), [jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L129–L131](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py#L129-L131) + + + + + +**落盘根由 JIUWENSWARM_DATA_DIR 决定,未设置或空白时默认 ~/.jiuwenswarm** +get_jiuwenswarm_data_dir 读取环境变量 JIUWENSWARM_DATA_DIR 并 strip,非空则 Path(raw).expanduser(),否则 Path.home()/".jiuwenswarm";local 目录固定追加 agent/workspace/plugins/plugin_packages/local。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L91–L103](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py#L91-L103) + + + + + +**拒绝覆盖已有包换取安全,代价是需重命名或删除;显式路径绕过重名预检** +设计推断(非作者历史意图): + +收益(推断):目标目录已存在时 raise 而非覆盖,避免破坏现有包,错误信息给出 rename/delete 两种出路。成本(推断):按名创建前须先处理旧包;且含分隔符的显式路径分支只校验父目录必须是 local 目录,不执行 _assert_package_id_available 的 local/built_in 重名检查。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L129–L147](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py#L129-L147), [jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L158–L162](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py#L158-L162) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-plugin-package-layered-validator.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-plugin-package-layered-validator.md new file mode 100644 index 00000000..fa301b39 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-plugin-package-layered-validator.md @@ -0,0 +1,82 @@ +--- +title: "plugin-creator 插件包分层校验器(L0/L1/L2):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py:L937-L952, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin_hot_load_worker.py:L328-L344, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin_hot_load_worker.py:L370-L376, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py:L157-L182, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin_hot_load_worker.py:L136-L155, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/SKILL.md:L1-L167, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py:L856-L876, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin_hot_load_worker.py:L361-L368, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py:L969-L971, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin_hot_load_worker.py:L122-L133, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py:L933-L971, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py:L844-L891] +feature: "plugin-package-layered-validator" +entry_points: ["jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py"] +source_globs: ["jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py", "jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin_hot_load_worker.py"] +--- + +# plugin-creator 插件包分层校验器(L0/L1/L2):实现深读 + +[功能概览](feature-plugin-package-layered-validator.md) · [owner 入口](_index.md) + + +**main:三层校验的分支、渲染与本地返回值** +main() 解析 target 与 --no-hot-load;resolve_pkg 失败时输出 Error 并 return 1。随后 validate_static(pkg) 得到 L0/L1 两层;--no-hot-load 或 L0/L1 有 errors 时构造 LAYER_HOT_LOAD 的 Layer 并 skip,否则调用 validate_hot_load(pkg) 在子进程中跑 worker 并解析最后一行 JSON。三层经 layer.render() 与 _print_summary 写到 stdout,仅当三层 status 全为 "PASS" 才 return 0,否则 return 1(函数返回值,非进程退出码断言)。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py:L933–L971](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py#L933-L971), [jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py:L844–L891](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py#L844-L891) + + + + + +**CLI:位置参数 target + --no-hot-load;找不到目录时输出 Error 并局部返回 1** +validate_plugin.py 接受一个位置参数 target(包目录绝对路径,或 local/ 下的 plugin-name)和 --no-hot-load 开关;resolve_pkg 抛 FileNotFoundError 时 write_stdout("Error: ...") 并 return 1(局部返回值,非进程级断言)。热加载 worker 是独立入口:要求恰好一个参数 ,向 stdout 输出一行 JSON 结果,status 为 pass/fail/其他时分别返回 0/1/2。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py:L937–L952](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py#L937-L952), [jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin_hot_load_worker.py:L328–L344](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin_hot_load_worker.py#L328-L344), [jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin_hot_load_worker.py:L370–L376](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin_hot_load_worker.py#L370-L376) + + + + + +**数据目录默认 ~/.jiuwenswarm,JIUWENSWARM_DATA_DIR 覆盖** +get_jiuwenswarm_data_dir 读取非空 JIUWENSWARM_DATA_DIR(expanduser),否则用 ~/.jiuwenswarm;resolve_pkg 先按参数找目录,找不到再到 local/ 下找,仍无则抛 FileNotFoundError。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py:L157–L182](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py#L157-L182) + + + + + +**L2 依赖 openjiuwen 运行时,ImportError 产生该次 skip 结果** +worker 在 _hot_load 内导入 openjiuwen 的 Runner/DeepAgent/Workspace 等;ImportError 时返回 skip 结果并提示换 JiuwenSwarm 的 venv python 重跑,本次不产出包级判定。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin_hot_load_worker.py:L136–L155](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin_hot_load_worker.py#L136-L155) + + + + + +**热加载 worker 超时或无法启动时父层记录 SKIP 并返回该层** +父脚本 subprocess.run 带 timeout=HOT_LOAD_TIMEOUT_SEC、check=False;捕获 subprocess.TimeoutExpired 与 OSError 时调用 layer.skip 记录原因与修复提示并 return layer,不抛异常。worker 侧 asyncio.run(_hot_load) 抛出的异常被捕获并转为 status="skip" 的结果。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py:L856–L876](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py#L856-L876), [jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin_hot_load_worker.py:L361–L368](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin_hot_load_worker.py#L361-L368) + + + + + +**子进程隔离+超时换取环境故障表现为 SKIP 而非错误** +设计推断(非作者历史意图): + +(推断)收益:热加载在子进程中执行并受 HOT_LOAD_TIMEOUT_SEC 约束,包内 import/绑定卡住不会无限阻塞校验;代价:超时/启动失败被记为 SKIP,而 970 行要求所有层 status == "PASS" 才返回 0,故基础设施故障同样导致整体返回 1,无法通过校验。另注意 _smoke_rail_callbacks 中单个回调抛异常是逐项记录为 error,不是整体 skip。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py:L856–L876](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py#L856-L876), [jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py:L969–L971](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py#L969-L971), [jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin_hot_load_worker.py:L122–L133](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin_hot_load_worker.py#L122-L133) + + + + + +**文档规定须跑到 RESULT: PASS 才能注册(未执行)** +文档中的人工验收步骤(本轮未执行): + +SKILL.md 要求 create/update 都执行 scripts/validate_plugin.py,L0/L1/L2 依次运行,须以 JiuwenSwarm 环境 python 达到 RESULT: PASS,L2 失败或未执行均不能 register。此为文档化手工流程,本次未执行。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/plugin-creator/SKILL.md:L1–L167](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/plugin-creator/SKILL.md#L1-L167) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ppt-deck-finalize.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ppt-deck-finalize.md new file mode 100644 index 00000000..affcf717 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ppt-deck-finalize.md @@ -0,0 +1,71 @@ +--- +title: "一键成片流水线与质量门禁(finalize_deck.py):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py:L117-L137, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py:L100-L109, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py:L192-L197, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py:L139-L146, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py:L56-L66, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py:L132-L137, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py:L44-L49] +feature: "ppt-deck-finalize" +entry_points: ["jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py"] +source_globs: ["jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py", "jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/make_blank_template.py", "jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/fill_cover.py", "jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/prune.py", "jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/merge_slides.py"] +--- + +# 一键成片流水线与质量门禁(finalize_deck.py):实现深读 + +[功能概览](feature-ppt-deck-finalize.md) · [owner 入口](_index.md) + + +**_run 在校验输入后用 run() 依次解包 template 与 content 到工作目录** +_run 解析参数后检查 content 与 template 文件存在且 content/out 不在 SKILL_ROOT 内;workdir 取 --keep-workdir 指定目录,否则新建临时目录,然后通过 run() 先后调用 unpack.py 解包 template 到 tdir、content 到 sdir。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py:L117–L137](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py#L117-L137) + + + + + +**CLI takes positional content and out; main maps FinalizeError to SystemExit** +finalize_deck.py accepts positional args `content` (generated content .pptx) and `out` (final .pptx to write); main() calls _run() and, on FinalizeError, raises SystemExit(str(exc)) chained from it, per its docstring keeping helpers usable as a library. + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py:L100–L109](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py#L100-L109), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py:L192–L197](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py#L192-L197) + + + + + +**Defaults: template.pptx, order "t1,s*,t5", slideLayout7.xml, source-layout-mode template** +--template defaults to SKILL_ROOT/references/template.pptx, --order defaults to "t1,s*,t5" (tN/sN/s* tokens), --template-layout defaults to slideLayout7.xml (Office's Blank), and --source-layout-mode accepts only "template" or "source", defaulting to "template". + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py:L100–L109](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py#L100-L109) + + + + + +**finalize_deck 通过 sys.executable 子进程调用同目录 scripts/opc/unpack.py,非零退出即抛 FinalizeError** +run() 用 subprocess.run([sys.executable, *argv]) 执行子脚本;SCRIPTS 定位为 finalize_deck.py 所在目录(SKILL_ROOT 为其父目录),_run() 先后调用 SCRIPTS/opc/unpack.py 解包模板与内容。任一子进程 returncode != 0 时抛 FinalizeError,提示用 --keep-workdir 检查中间目录。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py:L56–L66](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py#L56-L66), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py:L132–L137](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py#L132-L137) + + + + + +**Zero content slides raise FinalizeError; main converts it to SystemExit with the message** +When count_slides(sdir) returns 0, _run raises FinalizeError("finalize_deck: no slides found in {content}"); main() catches FinalizeError and re-raises SystemExit(str(exc)), terminating the process with the fatal message. + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py:L139–L146](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py#L139-L146), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py:L192–L197](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py#L192-L197) + + + + + +**helpers 抛 FinalizeError 而非 SystemExit 以保持库可用;代价是进程入口需自责转换** +设计推断(非作者历史意图): + +FinalizeError 的 docstring 说明在入口外抛 SystemExit 被禁止且使函数无法作库使用;main() 捕获 FinalizeError 并转为 SystemExit(str(exc))。推断的代价:经由 main() 运行时错误以退出消息呈现,库式调用方需自行捕获 FinalizeError。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py:L44–L49](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py#L44-L49), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py:L192–L197](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py#L192-L197) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ppt-evidence-preparation.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ppt-evidence-preparation.md new file mode 100644 index 00000000..073d0dde --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ppt-evidence-preparation.md @@ -0,0 +1,60 @@ +--- +title: "Evidence Plan Preparation and Review Lifecycle:实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py:L294-L316, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py:L95-L102, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py:L52-L53, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py:L322-L356, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py:L243-L253, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py:L134-L141, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py:L256-L260, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py:L346-L349, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py:L68-L70] +feature: "ppt-evidence-preparation" +entry_points: ["jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py"] +source_globs: ["jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py"] +--- + +# Evidence Plan Preparation and Review Lifecycle:实现深读 + +[功能概览](feature-ppt-evidence-preparation.md) · [owner 入口](_index.md) + + +**main() prepares only preparable planned/retried items, then saves plan and builds contact sheet, returning 0** +With no --approve/--used/--reject, main() loops plan items; an item is prepared only when its status is in PREPARABLE_STATUSES {"planned", "acquiring", "needs-manual"} and it is planned, explicitly selected, or --force. After the loop it saves the plan, builds the contact sheet, logs warnings, and returns 0 from this function. + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py:L52–L53](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py#L52-L53), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py:L322–L356](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py#L322-L356) + + + + + +**use_item(): non-native items need an existing path (else FileNotFoundError) and review.status=="approved" (else ValueError)** +use_item marks native-chart/native-drawing items used directly; other items raise FileNotFoundError if the resolved path is missing, ValueError if review.status is not "approved", and only then set status to "used". + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py:L243–L253](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py#L243-L253) + + + + + +**CLI 默认值与目录默认:--plan 默认 evidence-plan.json,根目录缺省 assets/ 与 analysis/** +argparse 定义位置参数 project,--plan 默认 "evidence-plan.json",--item/--approve/--used/--reject 为可重复列表,--force 为开关;plan 中的 asset_root 缺省回退到 root/"assets",analysis_root 回退到 root/"analysis",二者经 relative_to 校验必须位于项目根内,否则记日志并返回 1。paper 选择器的 min_confidence 默认 0.55。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py:L294–L316](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py#L294-L316), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py:L95–L102](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py#L95-L102) + + + + + +**prepare_paper shells out to sibling extractor with check=True; make_contact_sheet silently skips when PIL is missing** +prepare_paper runs extract_arxiv_visuals_v2_2.py via subprocess.run(check=True) with --force when force or the output dir exists, so an extractor failure raises; make_contact_sheet returns without output if PIL cannot be imported. + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py:L134–L141](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py#L134-L141), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py:L256–L260](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py#L256-L260) + + + + + +**Per-item exceptions are caught, set needs-manual, and continue the loop** +In main's item loop, any Exception during review/prepare (e.g. copy_asset raising FileNotFoundError at L69-70) is caught: the item's status becomes "needs-manual", review becomes {"status":"pending","notes":}, and the error string is appended to errors for later warning logging. + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py:L346–L349](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py#L346-L349), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py:L68–L70](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py#L68-L70) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ppt-execution-lock-validator.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ppt-execution-lock-validator.md new file mode 100644 index 00000000..37e15d54 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ppt-execution-lock-validator.md @@ -0,0 +1,60 @@ +--- +title: "PPT 执行锁(execution-lock.json)语义校验器:实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L201-L232, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L234-L247, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L249-L252, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L11-L19, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L11-L14, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L226-L231, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L16-L19, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L8-L9, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L183-L195, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L234-L241] +feature: "ppt-execution-lock-validator" +entry_points: ["jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js"] +source_globs: ["jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js", "jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-evidence-plan.js"] +--- + +# PPT 执行锁(execution-lock.json)语义校验器:实现深读 + +[功能概览](feature-ppt-execution-lock-validator.md) · [owner 入口](_index.md) + + +**以 --phase design|generate|deliver 运行时的校验路径:逐资产检查后汇总并按错误数退出** +argv 解析出 phase(默认 design)与 lock 路径后,脚本遍历 lock.assets 检查 id/kind/status/path 等,再校验每页 evidence_visual 引用,最后打印 [WARN]/[ERROR] 与统计行,并 process.exit(errors.length ? 1 : 0)。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L201–L232](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js#L201-L232), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L234–L247](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js#L234-L247), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L249–L252](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js#L249-L252) + + + + + +**CLI 契约:形如 --phase 显式跟随值的调用;缺参或非法 phase 退出码 2,有错误退出码 1、否则 0** +调用方须传 lock 路径且 phase 属于 design|generate|deliver,否则输出 Usage 并 process.exit(2)。注意 lockArg 的查找会排除 --phase 本身及其后一个参数,因此实际调用应让路径不在这些位置。汇总后按 errors 数量退出 1 或 0。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L11–L19](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js#L11-L19), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L249–L252](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js#L249-L252) + + + + + +**phase 默认 design;非 design 拒绝未就绪的必需资产,deliver 进一步要求 used** +--phase 缺省时 phase 为 "design"。phase !== "design" 且 asset.required 时,status 为 planned/acquiring/needs-manual 之一即报错;phase === "deliver" 时必需资产 status 非 used 报错。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L11–L14](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js#L11-L14), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L226–L231](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js#L226-L231) + + + + + +**version 2 锁通过 require 的 validateEvidencePlan 复用 evidence-plan 校验** +脚本第 9 行 require ./validate-evidence-plan.js;当 lock.version === 2 且 evidence_plan 非空、文件存在时(L183–L190),调用 validateEvidencePlan(evidencePath, { phase, pageIds })(L191),将其 errors/warnings 并入自身输出(L193–L194),并用返回的 itemsById 检查每页 evidence_visual.asset_ids 是否已知且属于该页(L237–L240)。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L8–L9](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js#L8-L9), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L183–L195](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js#L183-L195), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L234–L241](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js#L234-L241) + + + + + +**缺参/非法 phase 走 Usage 分支退出 2;任意校验错误累积为 [ERROR] 并以退出码 1 传播** +lockArg 为空或 phase 不在 design|generate|deliver 时立即 console.error(Usage) 并 process.exit(2);否则各检查通过 error() 记入 errors,结尾逐条打印并以 errors.length ? 1 : 0 退出,warning 仅打印不影响退出码。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L16–L19](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js#L16-L19), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L249–L252](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js#L249-L252) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ppt-figure-panel-layout.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ppt-figure-panel-layout.md new file mode 100644 index 00000000..86952b15 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ppt-figure-panel-layout.md @@ -0,0 +1,53 @@ +--- +title: "PPT 图表面板布局引擎(figure-panel.js):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L1-L7, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L17-L21, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L34-L35, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L82-L101, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L42-L75, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L82-L88, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L26-L37, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L83-L87] +feature: "ppt-figure-panel-layout" +entry_points: ["jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js"] +source_globs: ["jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js"] +--- + +# PPT 图表面板布局引擎(figure-panel.js):实现深读 + +[功能概览](feature-ppt-figure-panel-layout.md) · [owner 入口](_index.md) + + +**renderFigurePanel:读尺寸→layoutFigures 分行缩放→逐图贴图并按需加标签** +renderFigurePanel 对每个 figure 调 pngSize 得宽高比,layoutFigures 在 bounds.w×h 内分行并整体缩放,随后内容不足时垂直居中(oy),逐 rect 调 slide.addImage,仅当 f.label 存在才 slide.addText 居中中文标签,返回 layoutFigures 的结果。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L82–L101](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js#L82-L101) + + + + + +**layoutFigures(figs, w, h) 纯几何返回 {rects, rows, scale, totalH};renderFigurePanel({slide, figures, bounds})** +figs 需带 ar 字段;返回 rects(含 i,x,y,w,h,labelY,相对区域左上角)、行数 rows、scale=min(1, 可用高/自然高和)、累计 totalH。renderFigurePanel 只接 slide(无 pres 参数),figures 元素需 path 与可选 label,bounds 需 x,y,w,h,返回布局结果。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L42–L75](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js#L42-L75), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L82–L88](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js#L82-L88) + + + + + +**非 PNG 或缺 IHDR 时同步 throw;文件描述符由 finally 保证关闭** +pngSize 先 openSync 再 try/finally closeSync;签名不是 0x89504e47 抛 `not a PNG: `,offset 12–16 非 "IHDR" 抛 `not a PNG: missing IHDR: `。异常沿 renderFigurePanel 同步上抛,无捕获分支。仅校验 24 字节头部,不证明完整 PNG 有效性。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L26–L37](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js#L26-L37), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L83–L87](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js#L83-L87) + + + + + +**全同步几何引擎换取可顺序调用;常量复制带来漂移风险(推断)** +设计推断(非作者历史意图): + +收益:全部同步使 slides.js 能按顺序调用组件、无需异步图片解码(注释明确此意图)。成本(推断):LABEL_FONT/LABEL_COLOR 复制自 components.js 而非共享来源,两处可能不同步漂移;且 pngSize 只认 IHDR 在固定偏移的 PNG,其他图片格式直接抛错。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L1–L7](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js#L1-L7), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L17–L21](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js#L17-L21), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L34–L35](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js#L34-L35) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ppt-opc-thumbnail.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ppt-opc-thumbnail.md new file mode 100644 index 00000000..520570fa --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ppt-opc-thumbnail.md @@ -0,0 +1,62 @@ +--- +title: "Deck Thumbnail Contact-Sheet Renderer:实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L52-L55, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L109-L111, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L126-L127, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L58-L63, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L71-L78, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L114-L116, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L135-L140, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L22-L37, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L106-L112, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L135-L144, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L58-L78, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L89-L103, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L40-L45] +feature: "ppt-opc-thumbnail" +entry_points: ["jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py"] +source_globs: ["jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py"] +--- + +# Deck Thumbnail Contact-Sheet Renderer:实现深读 + +[功能概览](feature-ppt-opc-thumbnail.md) · [owner 入口](_index.md) + + +**CLI: positional deck, optional prefix (default "thumbnails"), --cols default 3; helpers raise ThumbnailError, main converts it to SystemExit** +argparse 定义 deck(必填)、prefix(默认 thumbnails)、--cols(默认 3)。程序输出经 _OUT logger(%(message)s 格式、propagate=False、stdout handler)走 stdout,诊断经 LOGGER 走 stderr;main 捕获 ThumbnailError 转为 SystemExit(str(exc)),__main__ 下 sys.exit(main())。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L22–L37](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py#L22-L37), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L106–L112](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py#L106-L112), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L135–L144](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py#L135-L144) + + + + + +**常量与 CLI 默认:prefix=thumbnails、cols=3、CELL_W=480、MAX_PER_SHEET=24** +输出前缀默认 “thumbnails”、列数默认 3;CELL_W=480px、LABEL_H=22、PAD=8 为模块常量;页数超过 MAX_PER_SHEET=24 时文件名追加 “-N” 后缀分片。运行时 soffice 转换 timeout=300 秒。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L52–L55](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py#L52-L55), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L109–L111](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py#L109-L111), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L126–L127](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py#L126-L127) + + + + + +**soffice subprocess, delayed fitz import, and PIL (Image/ImageDraw) composition** +render_pages 以 find_soffice() 返回的可执行文件运行 `--headless --convert-to pdf`(check=True, capture_output, timeout=300 的 subprocess 参数),随后延迟 import fitz 并用 fitz + PIL Image 栅格化;build_sheet 用 Image.new/ImageDraw 拼网格。缺 soffice 或 PyMuPDF 分别抛出指明安装方式的 ThumbnailError。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L58–L78](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py#L58-L78), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L89–L103](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py#L89-L103) + + + + + +**ThumbnailError 路径:soffice 缺失、无 PDF、缺 PyMuPDF、deck 不存在** +find_soffice 找不到 soffice 或 mac 路径时抛 ThumbnailError;LibreOffice 未产出 PDF 文件、fitz ImportError、deck 非文件均抛 ThumbnailError;main() 将其转为 SystemExit(错误消息),使 helper 保持可库用。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L58–L63](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py#L58-L63), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L71–L78](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py#L71-L78), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L114–L116](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py#L114-L116), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L135–L140](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py#L135-L140) + + + + + +**Bundling rendering into helpers with ThumbnailError keeps library usability (inference), at the cost of external soffice/PyMuPDF requirements** +设计推断(非作者历史意图): + +收益(推断):按 docstring L41–L45,helpers 抛 ThumbnailError 而非 SystemExit,使其可作为库复用。成本:必须找到 soffice 且 fitz 可导入,否则以 ThumbnailError 失败;L70 的 timeout=300 是传给 subprocess.run 的设置参数,本片证据不构成对实际耗时的硬性保证。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L40–L45](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py#L40-L45), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L58–L78](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py#L58-L78) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ppt-system-diagram-renderer.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ppt-system-diagram-renderer.md new file mode 100644 index 00000000..74490bdf --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ppt-system-diagram-renderer.md @@ -0,0 +1,60 @@ +--- +title: "PPT 系统架构图原生形状渲染引擎:实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/components.js:L1733-L1736, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/components.js:L17-L21, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/components.js:L1722-L1737, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/system-diagram.js:L797-L802, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/components.js:L10-L13, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/components/diagrams.js:L4-L17, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/system-diagram.js:L145-L158, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/components.js:L1728-L1737, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/system-diagram.js:L1-L10] +feature: "ppt-system-diagram-renderer" +entry_points: ["jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/system-diagram.js"] +source_globs: ["jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/system-diagram.js", "jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/components.js"] +--- + +# PPT 系统架构图原生形状渲染引擎:实现深读 + +[功能概览](feature-ppt-system-diagram-renderer.md) · [owner 入口](_index.md) + + +**addSystemDiagram 按区域宽度选 density 后调用 renderSystemDiagram 画原生形状** +components.js 的 addSystemDiagram(pres, slide, {spec, x=0.5, y=1.05, w=9.0, h=3.6, density, heading}) 先校验 slide 并警告区域重叠;可选 heading 先画标题并从 h 中扣减标题高度;density 缺省时按宽度选 full(w>=8)/split(w>=4)/compact,把对应 fontMin/fontMax 合入 DEFAULT_THEME 后调用 system-diagram.js 的 renderSystemDiagram,返回布局描述符 {bounds, nodes, groups, edgeLabels, warnings}。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/components.js:L1728–L1737](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/components.js#L1728-L1737), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/system-diagram.js:L1–L10](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/system-diagram.js#L1-L10) + + + + + +**addSystemDiagram 契约:区域默认 (0.5, 1.05, 9.0, 3.6),返回布局描述符** +签名 addSystemDiagram(pres, slide, { spec, x=0.5, y=1.05, w=9.0, h=3.6, density, heading });调用方传入 Diagram IR spec,density 缺省按宽度自动选择,返回引擎布局描述符 { bounds, nodes, groups, edgeLabels, warnings } 供 QA 与 diagram-verifier 不重解析 PPTX 即可检查几何。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/components.js:L1722–L1737](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/components.js#L1722-L1737), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/system-diagram.js:L797–L802](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/system-diagram.js#L797-L802) + + + + + +**density 省略时按区域宽度自动选择:w>=8 为 full,w>=4 为 split,否则 compact** +默认区域 w=9.0 落入 full(fontMin 7 / fontMax 13);split 限 6.5–11,compact 限 6–9.5;显式传入未知 density 时回退 DIAGRAM_DENSITY.full。字体制数覆盖 DEFAULT_THEME 同名字段。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/components.js:L1733–L1736](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/components.js#L1733-L1736), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/components.js:L17–L21](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/components.js#L17-L21) + + + + + +**components.js 同级 require system-diagram.js,diagrams.js 从 components.js 转口 API** +components.js 通过 require(path.join(__dirname, "system-diagram.js")) 取得渲染引擎并(经 addSystemDiagram 与构造器)供外部使用;components/diagrams.js 仅 require ../scripts/components.js 并转口 addSystemDiagram、addPipelineDiagram 等及 item/group/bandNode/groupBand,不导出 renderSystemDiagram 或 DEFAULT_THEME。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/components.js:L10–L13](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/components.js#L10-L13), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/components/diagrams.js:L4–L17](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/components/diagrams.js#L4-L17) + + + + + +**fail loud 拒绝 left_to_right:换取可测量性,代价是既有调用方必须改写** +实现注释(L145–L150)解释 left_to_right 被移除是因该路径不测量内容、top_to_bottom 装不下时报 OVER-CAPACITY 会把作者推向宽松路径,故选择 fail loud 并在错误中指引改用 addPipelineDiagram;代价是使用该 orientation 的调用方直接得到异常、需删字段或换 API。此取舍叙述来自源码注释,属实现的既述理由。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/system-diagram.js:L145–L158](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/system-diagram.js#L145-L158) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-pptx-structural-audit.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-pptx-structural-audit.md new file mode 100644 index 00000000..27ce1c22 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-pptx-structural-audit.md @@ -0,0 +1,62 @@ +--- +title: "PPTX 结构与可读性审计脚本:实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L494-L534, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L506-L509, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L59-L64, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L511-L517, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L295-L308, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L2-L7, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L268-L274, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L11-L20, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L55-L56] +feature: "pptx-structural-audit" +entry_points: ["jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py"] +source_globs: ["jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py", "jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/qa_density.py", "jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/qa_geometry.py"] +--- + +# PPTX 结构与可读性审计脚本:实现深读 + +[功能概览](feature-pptx-structural-audit.md) · [owner 入口](_index.md) + + +**main 解析参数后调用 audit,报告写入/输出并以错误数决定返回值** +main 配置 stderr 日志、解析参数,调用 audit(args);成功时可选写 --report JSON,逐条输出 warnings/errors 及汇总行,仅当 report["errors"] 非空时返回 1,否则返回 0。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L494–L534](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py#L494-L534) + + + + + +**字号下限默认 24/10/7 可由 CLI 覆盖;幻灯尺寸缺省 12192000x6858000 EMU** +--title-min-font、--body-min-font、--absolute-min-font 的 argparse 默认分别为 24.0、10.0、7.0;slide_size 在 presentation.xml 缺少 p:sldSz 节点或属性时回退到 12192000x6858000 EMU(16:9)。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L506–L509](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py#L506-L509), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L59–L64](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py#L59-L64) + + + + + +**audit_pptx.py depends only on the Python standard library and reads the PPTX as a ZIP of XML** +Imports are argparse, hashlib, json, logging, posixpath, re, sys, zipfile, pathlib and xml.etree.ElementTree only; the xml() helper parses parts via ET.fromstring(zf.read(name)), so the audit runs without python-pptx or other third-party packages. + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L11–L20](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py#L11-L20), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L55–L56](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py#L55-L56) + + + + + +**输入/解析异常被捕获并返回 1;缺失包部件记为 errors** +main 捕获 (OSError, ValueError, zipfile.BadZipFile, ET.ParseError),日志输出 "audit failed: ..." 并返回 1;audit 内部对不存在的 pptx 路径抛 FileNotFoundError,对缺失的必需包部件(如 ppt/presentation.xml)追加到 errors 列表而非立即抛出。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L511–L517](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py#L511-L517), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L295–L308](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py#L295-L308) + + + + + +**主题色外置到 lock 便于换肤,但视觉验收仍需人工/Agent** +设计推断(非作者历史意图): + +收益:summary_band 的期望填充色来自锁文件而非硬编码,重主题化 deck 不需要修改检查。成本:docstring 明确视觉 contact sheet 仍需 Agent 目检,脚本只覆盖结构与可读性维度。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L2–L7](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py#L2-L7), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L268–L274](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py#L268-L274) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-rsi-dataset-folder-check.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-rsi-dataset-folder-check.md new file mode 100644 index 00000000..d3090814 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-rsi-dataset-folder-check.md @@ -0,0 +1,73 @@ +--- +title: "RSI 数据集任务文件夹完整性预检:实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L1-L9, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L67-L73, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L67-L83, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L210-L218, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L99-L127, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L59-L64, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L72-L85, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L210-L214, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L195-L208, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/SKILL.md:L265-L290] +feature: "rsi-dataset-folder-check" +entry_points: ["jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py"] +source_globs: ["jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py"] +--- + +# RSI 数据集任务文件夹完整性预检:实现深读 + +[功能概览](feature-rsi-dataset-folder-check.md) · [owner 入口](_index.md) + + +**main():校验参数后读取 run/scorecard.json,收集 problems 并以 0/1 返回** +argv 不是恰好 2 个时记录 __doc__ 并返回 1;否则读取 root/run/scorecard.json,逐项把问题追加到 problems 列表,最后拼成一条消息用 logger.info 输出(无问题时为 "ok: …"),并返回 1 if problems else 0。该返回值经 L217-218 的 sys.exit(main()) 变为进程退出码。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L67–L83](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py#L67-L83), [jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L210–L218](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py#L210-L218) + + + + + +**CLI contract: exactly one argument (task folder); wrong arity logs __doc__ and returns 1** +Callers invoke `python scripts/check_folder.py `; if len(sys.argv) != 2 the script logs its docstring and returns 1. It never imports the seed or runs the evaluator — it only checks shape, key sets, and numeric floors. + +来源:[jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L1–L9](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py#L1-L9), [jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L67–L73](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py#L67-L73) + + + + + +**检查结果依赖 task.json 的 files_in_seed/artifact_path 与 seed/ 目录遍历一致** +脚本用 rglob("*") 遍历 seed/,跳过目录、.pyc 与含 __pycache__/、.git/、node_modules/、.venv/ 的相对路径,排序后要求 task.json 的 files_in_seed 与该清单相等,artifact_path 须等于按文件数推导的 expected,否则追加 problem——即清单或路径不同步会让文件夹被判不完整。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L99–L127](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py#L99-L127), [jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L59–L64](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py#L59-L64) + + + + + +**缺失文件走 problems 分支返回 1;scorecard.json 的读取与 JSON 解析无守卫,异常直接抛出** +seed/ 不是目录、task.json 不是文件时分别追加 "no seed/ directory"、"no task.json" 并最终返回 1;但 L73 对 run/scorecard.json 的 read_text/json.loads 没有 try 分支,文件缺失或非法 JSON 会以未捕获异常终止,而不是进入 problems 汇总路径。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L72–L85](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py#L72-L85), [jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L210–L214](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py#L210-L214) + + + + + +**traceback 嗅探只进 warnings 不进 problems:不改变退出码,代价是只能提示无法证明** +设计推断(非作者历史意图): + +当 evaluator_file 以 .py 结尾且 script 含 "except" 却不含 "traceback" 时,只 logger.warning 提示(PROBE_REFUSED 风险),return 仍由 problems 单独决定——好处是不因文本启发式误判文件夹不完整,成本是注释自述这只是“smell”,无法测试运行时行为。(推断:益处为本实现的直接后果) + +来源:[jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L195–L208](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py#L195-L208), [jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L210–L214](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py#L210-L214) + + + + + +**文档化的手工程序:运行 check_folder.py 并确认输出 ok(未执行)** +文档中的人工验收步骤(本轮未执行): + +SKILL.md 记载交付前运行 `python scripts/check_folder.py `,并要求第 2 项检查“上述检查打印 ok”;同时说明它只查形状/键集/数值下限,不导入 seed、不运行 evaluator。此为已记载的手工步骤,本轮未执行,不能据此声称测试已通过。validation_kind: documented_manual。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/SKILL.md:L265–L290](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/SKILL.md#L265-L290) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-skill-generator-cli.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-skill-generator-cli.md new file mode 100644 index 00000000..475a3faa --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-skill-generator-cli.md @@ -0,0 +1,53 @@ +--- +title: "skill-gen CLI(sop-text / url-fetch 子命令):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_generator_cli.py:L61-L96, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L444-L455, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_generator_cli.py:L61-L65, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_generator_cli.py:L84-L88, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/url_ingest/web_page.py:L126-L141, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_generator_cli.py:L81-L96, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_generator_cli.py:L47-L58, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/url_ingest/router.py:L31-L41] +feature: "skill-generator-cli" +entry_points: ["jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_generator_cli.py"] +source_globs: ["jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_generator_cli.py", "jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/url_ingest/web_page.py", "jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/url_ingest/__init__.py", "jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/url_ingest/models.py", "jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/url_ingest/router.py", "jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/url_ingest/wechat_article.py"] +--- + +# skill-gen CLI(sop-text / url-fetch 子命令):实现深读 + +[功能概览](feature-skill-generator-cli.md) · [owner 入口](_index.md) + + +**url-fetch with a non-WeChat URL: trimmed input routed to the generic fetcher, pages serialized, return 0** +In _cmd_url_fetch, a stripped-empty --url logs "error: empty --url" and returns 2 locally; otherwise fetch_pages_from_url is awaited, each FetchedPage is converted via asdict to indent=2 JSON, written to --out-json (parent dirs created) or emitted to stdout by the dedicated stdout_payload logger (INFO, propagate disabled), and the handler returns 0. The router strips the URL, generates a uuid4 doc_id, and dispatches to fetch_web_page when is_wechat_article_url is false. + +来源:[jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_generator_cli.py:L81–L96](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_generator_cli.py#L81-L96), [jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_generator_cli.py:L47–L58](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_generator_cli.py#L47-L58), [jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/url_ingest/router.py:L31–L41](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/url_ingest/router.py#L31-L41) + + + + + +**sop-text extracts raw text; url-fetch fetches pages as JSON** +_cmd_sop_text takes --sop-file (expanded/resolved), and with --print-raw-chars logs len(raw) and returns 0; with --out-text writes the file (mkdir parents) and returns 0; otherwise logs raw text. _cmd_url_fetch requires a non-empty --url, awaits fetch_pages_from_url, and writes or logs json.dumps of [asdict(p)] with --out-json. + +来源:[jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_generator_cli.py:L61–L96](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_generator_cli.py#L61-L96) + + + + + +**CLI 两个前置守卫返回 2;fetch_web_page 的抓取异常被改写为 ValueError 且 _cmd_url_fetch 不捕获** +_cmd_sop_text 中 expanduser/resolve 后非普通文件则 logger.error 并 return 2;_cmd_url_fetch 中空白 --url 同样 return 2(均为函数返回值)。fetch_web_page 的 try 块把 HTTPStatusError(含状态码)与 RequestError 等异常改写为带 URL 的 ValueError;_cmd_url_fetch 未捕获 ValueError,异常沿 await 上抛。解析后正文节点缺失或文本不足 50 字符也抛 ValueError。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_generator_cli.py:L61–L65](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_generator_cli.py#L61-L65), [jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_generator_cli.py:L84–L88](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_generator_cli.py#L84-L88), [jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/url_ingest/web_page.py:L126–L141](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/url_ingest/web_page.py#L126-L141) + + + + + +**Optional parser dependency: graceful fallback vs format loss** +设计推断(非作者历史意图): + +Inference: making AutoFileParser optional (ImportError fallback to plain read) lets sop-text run without agent-core, but costs support for non-text suffixes, which raise "无法解析 SOP 文件..." telling the user to install agent-core or provide .md/.txt. + +来源:[jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L444–L455](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py#L444-L455) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-skill-page-scrape-blocks.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-skill-page-scrape-blocks.md new file mode 100644 index 00000000..4fecd061 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-skill-page-scrape-blocks.md @@ -0,0 +1,71 @@ +--- +title: "Web Page Scraping to Unified Stage01 Blocks:实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L820-L880, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L820-L876, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L885-L895, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L825-L835, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L718-L757, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L977-L986, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L969-L987, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L753-L757] +feature: "skill-page-scrape-blocks" +entry_points: ["jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py"] +source_globs: ["jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py", "jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/print_blocks.py", "jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/common.py", "jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/download_images.py", "jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/environment_gate.py"] +--- + +# Web Page Scraping to Unified Stage01 Blocks:实现深读 + +[功能概览](feature-skill-page-scrape-blocks.md) · [owner 入口](_index.md) + + +**scrape_page_playwright: headless Chromium fetch of the exact URL, parse, dedupe, conditional platform-URL prepend** +scrape_page_playwright launches headless Chromium, scrapes one page, and parses html into blocks only when html is non-empty; image blocks are deduplicated by URL keeping first occurrence, video_urls deduplicated, and page_url inserted at index 0 only if is_platform_url(page_url) and it is not already in video_urls. Returns (deduped, video_urls, page_title). + +来源:[jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L820–L876](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py#L820-L876) + + + + + +**scrape_page wraps the async Playwright path synchronously** +scrape_page(url: str) -> tuple[list[dict], list[str], str] returns asyncio.run(scrape_page_playwright(url)); the async function imports playwright.async_api locally and its docstring states it scrapes only the exact URL supplied, never following page links. Callers get unified blocks, video URLs, and the page title. + +来源:[jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L820–L880](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py#L820-L880) + + + + + +**main() argparse defaults: optional url/slug, --out default None, --check-deps flag** +main() declares url with nargs="?" (optional), slug nargs="?" default None, --out default None, and boolean --check-deps described as running the shared environment gate with auto-repair then exiting; the shown slice ends at parse_args() so downstream handling of these values is not visible here. + +来源:[jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L885–L895](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py#L885-L895) + + + + + +**scrape_one_page requires a caller-supplied Playwright page and common module constants** +scrape_one_page(page, page_url, dismiss_cookie=False) 接收外部传入的 Playwright page:先 add_init_script 注入 canvas 文本补丁,再用 page.goto(page_url, wait_until="commit", timeout=common.PAGE_LOAD_TIMEOUT_SECONDS * 1000) 导航,超时常量来自共享 common 模块。主流程随后依赖 build_bounded_stage01_payload 与 common.write_json 落盘 stage01。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L718–L757](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py#L718-L757), [jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L977–L986](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py#L977-L986) + + + + + +**Empty or marker-blocked blocks only log a warning and still write a bounded stage01 payload** +在主流程中,当 blocks 为空或(无图片块且正文命中 _blocked_markers)时,仅输出两条 logger.warning(含用 web_fetch_webpage 兜底的提示),不抛错;随后仍构造 build_bounded_stage01_payload 并 common.write_json 写出 stage01,limits 来自 payload["content_limits"]。另外 scrape_one_page 内 resp.status >= 400 有显式判断分支入口(其后续语句未在展示范围内)。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L969–L987](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py#L969-L987), [jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L753–L757](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py#L753-L757) + + + + + +**Chromium launch flags trade HTTP/2 for fingerprint compatibility (inference from in-code comment)** +设计推断(非作者历史意图): + +The browser is launched with --disable-http2 alongside --no-sandbox and related flags; the code comment states some sites reject Playwright's H2 fingerprint with ERR_HTTP2_PROTOCOL_ERROR. Inference: forcing HTTP/1.1 trades multiplexing performance for compatibility with such sites — the benefit/cost is my reading of the comment, not a measured outcome. + +来源:[jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L825–L835](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py#L825-L835) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-sop-structure-extraction.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-sop-structure-extraction.md new file mode 100644 index 00000000..a7b4b665 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-sop-structure-extraction.md @@ -0,0 +1,44 @@ +--- +title: "SOP 结构化抽取(parse_sop_raw_text / parse_sop_file):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L14-L15, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_chunk_merge.py:L559-L560, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/__init__.py:L3-L21, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L349-L363, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L289-L306, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L349-L364, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L371-L391] +feature: "sop-structure-extraction" +entry_points: ["jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py"] +source_globs: ["jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py", "jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_chunk_merge.py", "jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_fallback.py", "jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/__init__.py", "jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/models.py"] +--- + +# SOP 结构化抽取(parse_sop_raw_text / parse_sop_file):实现深读 + +[功能概览](feature-sop-structure-extraction.md) · [owner 入口](_index.md) + + +**auto 模式按 room_single 判定分块,否则单次抽取并记录弱抽取原因** +mode 为 auto 时仅当 len(raw_text) > room_single 才走 extract_structure_chunked(run_reconcile=True),否则截断到 room_single 走单次抽取;随后计算 weak_reasons,置 sop.raw_text=raw_text 并返回 (sop, extraction_meta)。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L289–L306](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py#L289-L306), [jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L349–L364](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py#L349-L364), [jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L371–L391](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py#L371-L391) + + + + + +**sop_parser 依赖 sop_chunk_merge 与 models.SOPStructure** +sop_parser.py 导入 extract_structure_chunked/extract_structure_single_shot 与 SOPStructure,抽取结果的 dict 经 SOPStructure.from_dict 转为结构化对象;包 __init__ 对外导出 parse_sop_raw_text/parse_sop_file 及 DEFAULT_SINGLE_SHOT_BUDGET。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L14–L15](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py#L14-L15), [jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_chunk_merge.py:L559–L560](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_chunk_merge.py#L559-L560), [jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/__init__.py:L3–L21](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/__init__.py#L3-L21) + + + + + +**超长单次输入截断换取成本可控,代价是提示不完整(推断)** +设计推断(非作者历史意图): + +非分块路径直接把 raw_text 截到 room_single 并在 merge_warnings 记 "single_shot_prompt_truncated_to_{n}_chars",避免分块多次调用;代价是截断后文档尾部信息不进入本次抽取(推断自 shown lines 350-363)。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L349–L363](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py#L349-L363) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-video-coarse-scan-frame-extraction.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-video-coarse-scan-frame-extraction.md new file mode 100644 index 00000000..07f19dea --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-video-coarse-scan-frame-extraction.md @@ -0,0 +1,73 @@ +--- +title: "视频粗扫抽帧与审核批次门控(analyze_video.py):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/analyze_video.py:L86-L88, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/analyze_video.py:L359-L371, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/analyze_video.py:L307-L323, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/analyze_video.py:L325-L330, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/analyze_video.py:L356-L356, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/analyze_video.py:L52-L74, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/analyze_video.py:L127-L146, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/analyze_video.py:L152-L175, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/analyze_video.py:L43-L49, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/analyze_video.py:L152-L188, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/analyze_video.py:L203-L210, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/analyze_video.py:L343-L354, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/analyze_video.py:L359-L396, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/SKILL.md:L144-L152] +feature: "video-coarse-scan-frame-extraction" +entry_points: ["jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/analyze_video.py"] +source_globs: ["jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/analyze_video.py"] +--- + +# 视频粗扫抽帧与审核批次门控(analyze_video.py):实现深读 + +[功能概览](feature-video-coarse-scan-frame-extraction.md) · [owner 入口](_index.md) + + +**slug 路径:候选视频须为非 .part 文件,全不合格时回退首候选并仅在不存在时退出** +main 中 slug 目标按 video.mp4、downloads/video.mp4、downloads/video.* 顺序取第一个 is_file() 且非 .part 的候选;无合格候选时回退 candidates[0],仅当该回退路径不存在时 sys.exit(1)。随后依次 probe_duration、choose_fps、extract_frames、build_review_frames,帧数为 0 则 sys.exit(1),最后写入 current_batch=1 状态并打印第 1 批路径。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/analyze_video.py:L343–L354](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/analyze_video.py#L343-L354), [jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/analyze_video.py:L359–L396](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/analyze_video.py#L359-L396) + + + + + +**CLI:target 必填,--title/--slug 可选,两个互斥批次旗标触发提前返回** +接受位置参数 target(视频 URL 或 slug);--title 默认 None(L356 回退为 slug 的下划线替换为空格);--slug 默认 None(URL 时经 common.resolve_work_slug_for_url 解析)。--current-review-batch 与 --next-review-batch 属互斥组,命中任一即调用 _show_or_advance_review_batch 并 return,不下载不抽帧。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/analyze_video.py:L307–L323](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/analyze_video.py#L307-L323), [jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/analyze_video.py:L325–L330](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/analyze_video.py#L325-L330), [jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/analyze_video.py:L356–L356](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/analyze_video.py#L356-L356) + + + + + +**抽帧频率默认由时长自适应:min(BASE_FPS, MAX_FRAMES/时长)** +choose_fps 无可调参数,短视频用 BASE_FPS,长视频按 MAX_FRAMES/时长降频,使总帧数逼近上限;main 中 fps=choose_fps(duration),interval=1/fps 仅用于日志展示。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/analyze_video.py:L86–L88](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/analyze_video.py#L86-L88), [jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/analyze_video.py:L359–L371](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/analyze_video.py#L359-L371) + + + + + +**ffprobe/ffmpeg 经 subprocess 调用,PIL 用于审核 JPEG 编码** +probe_duration/extract_frames 以 subprocess.run 调用外部 ffprobe/ffmpeg(timeout=common.OPERATION_TIMEOUT_SECONDS),FileNotFoundError 与非零返回码被转换为 RuntimeError(超时异常未被捕获);_encode_review_jpeg 用 PIL Image 打开、转 RGB、LANCZOS 缩放并保存 JPEG。二者不在系统内时脚本无法工作。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/analyze_video.py:L52–L74](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/analyze_video.py#L52-L74), [jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/analyze_video.py:L127–L146](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/analyze_video.py#L127-L146), [jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/analyze_video.py:L152–L175](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/analyze_video.py#L152-L175) + + + + + +**审核 JPEG 代理压低模型读取体积,代价是每帧/每批字节预算超限即 RuntimeError 失败** +设计推断(非作者历史意图): + +受益:原始 frames/ PNG 保持不变,审核走 480x270/384x216、quality 50-60 的 JPEG 代理以控制读取体积(推断自常量与注释)。成本:_encode_review_jpeg 四次尝试后仍超过 REVIEW_MAX_BYTES=45*1024 会抛 RuntimeError,build_review_frames 在任一批字节总和超过 REVIEW_BATCH_MAX_BYTES=225*1024 时抛 RuntimeError,阻断完成。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/analyze_video.py:L43–L49](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/analyze_video.py#L43-L49), [jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/analyze_video.py:L152–L188](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/analyze_video.py#L152-L188), [jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/analyze_video.py:L203–L210](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/analyze_video.py#L203-L210) + + + + + +**SKILL.md 记载的手动验证流程(未执行)** +文档中的人工验收步骤(本轮未执行): + +SKILL.md 给出具体命令:analyze_video.py "" --title "...",并说明短视频 0.5fps、长视频均匀覆盖且总帧数最多 90、每批最多 5 帧,首次只打印第 1 批审核帧路径,完成后追加 --next-review-batch 获取下一批。这是文档记载的手动流程,本次未执行;未提供覆盖该脚本的自动化测试证据。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/SKILL.md:L144–L152](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/SKILL.md#L144-L152) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-xlsx-add-computed-column.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-xlsx-add-computed-column.md new file mode 100644 index 00000000..bf0c5eb4 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-xlsx-add-computed-column.md @@ -0,0 +1,71 @@ +--- +title: "XLSX Computed Column Adder:实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L67-L115, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L57-L78, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py:L50-L77, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L28-L38, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L105-L109, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L21-L25, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L67-L78, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L51-L65, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L111-L116, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L104-L109, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py:L242-L257] +feature: "xlsx-add-computed-column" +entry_points: ["jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py"] +source_globs: ["jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py"] +--- + +# XLSX Computed Column Adder:实现深读 + +[功能概览](feature-xlsx-add-computed-column.md) · [owner 入口](_index.md) + + +**main(): resolve sheet, patch styles, write header/formula/total cells, then repack-ready save** +main() splits the target column ref, resolves the worksheet (defaulting to the first sheet name from workbook.xml), builds Styles, adds numfmt/border entries, writes optional header, formula cells for --formula-rows via {row} substitution, optional total cell, optional row-wide top border, then sorts sheetData, updates dimension, saves styles and writes the worksheet XML, printing "added column on ''". + +来源:[jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L67–L115](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py#L67-L115) + + + + + +**main():位置参数 workdir 加 --col(必填)等选项,成功后打印并局部 return 0** +命令行契约:位置参数 workdir,--col 必填;--header-row 默认 1,--border-style 默认 "medium",--sheet/--header/--formula/--formula-rows/--total-row/--total-formula/--numfmt/--border-row 可选。成功路径先排序、更新 dimension、保存 styles 与 worksheet XML,打印 "added column …" 后局部 return 0(不构成进程退出码证明)。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L51–L65](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py#L51-L65), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L111–L116](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py#L111-L116) + + + + + +**Defaults within main(): header-row 1, border-style "medium", sheet falls back to first sheet** +When --sheet is omitted, sheet = X.first_sheet_name(args.workdir), i.e. the first in xl/workbook.xml. --header-row defaults to 1 and --border-style defaults to "medium"; style wiring is conditional: data_xf is created only if a --numfmt was given, and total_xf/border styles only if --border-row is set. + +来源:[jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L57–L78](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py#L57-L78) + + + + + +**Imports _xlsx_common and resolves the target sheet through workbook.xml and its .rels** +xlsx_add_column.py imports _xlsx_common as X and uses its first_sheet_name/resolve_worksheet/Styles helpers; resolve_worksheet maps the sheet display name to an r:id in xl/workbook.xml and then to a Target in xl/_rels/workbook.xml.rels, raising SystemExit("sheet not found: …") or "relationship not found…" when either lookup fails. + +来源:[jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L21–L25](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py#L21-L25), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L67–L78](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py#L67-L78), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py:L50–L77](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py#L50-L77) + + + + + +**Sheet resolution failures raise SystemExit with message; border pass preserves each cell's numFmtId** +resolve_worksheet raises SystemExit("sheet not found: ") when the display name is absent from workbook.xml and SystemExit("relationship not found for sheet: ...") when the r:id has no matching relationship entry; first_sheet_name raises SystemExit("no sheets found in workbook.xml") if workbook.xml has no sheet. In the border pass, numfmt_of returns numFmtId 0 when the cell's style index or cellXfs is missing, so add_xf is still applied. + +来源:[jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py:L50–L77](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py#L50-L77), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L28–L38](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py#L28-L38), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L105–L109](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py#L105-L109) + + + + + +**--border-row 保留各单元格 numFmtId,但新 xf 将 fontId/fillId 固定为 0 且逐格追加 xf** +设计推断(非作者历史意图): + +推断:行级加顶边框时用 numfmt_of 读取原样式的 numFmtId 并写入新 xf,避免破坏数字格式;代价是每个单元格的字体/填充被重置为 fontId="0"、fillId="0",且 add_xf 为每个单元格追加新 cellXfs 条目而非复用。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L104–L109](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py#L104-L109), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L28–L38](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py#L28-L38), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py:L242–L257](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py#L242-L257) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-xlsx-doctor-selfcheck.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-xlsx-doctor-selfcheck.md new file mode 100644 index 00000000..46113dab --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-xlsx-doctor-selfcheck.md @@ -0,0 +1,62 @@ +--- +title: "XLSX 技能环境自检(doctor.py):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L104-L134, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L8-L11, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L105-L107, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L118-L130, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L133-L134, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L50-L61, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L64-L71, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L74-L93, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L56-L61, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L86-L101, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L115-L116, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L34-L37, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L86-L96] +feature: "xlsx-doctor-selfcheck" +entry_points: ["jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py"] +source_globs: ["jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py"] +--- + +# XLSX 技能环境自检(doctor.py):实现深读 + +[功能概览](feature-xlsx-doctor-selfcheck.md) · [owner 入口](_index.md) + + +**main 顺序执行四类检查并按 required 失败决定返回值** +main() 依次调用 check_python/check_py_deps/check_cli/check_cjk_font 填充 results;若没有任何 required 且 not ok 的项则局部返回 0,否则返回 1,由 __main__ 的 sys.exit 传出。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L104–L134](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py#L104-L134) + + + + + +**doctor.py 命令行入口:--json 为唯一显式新增选项,输出两种格式并由 main 返回 0/1** +用法为 python3 doctor.py [--json](L8–L11;argparse 默认还会提供 -h/--help)。默认打印人类可读的 PASS/FAIL/warn 报告;--json 时打印 {"ok":…,"results":[…]} 的 JSON(L118–L119)。main 在无必需项失败时返回 0,否则返回 1(L130),由 L133–L134 的 sys.exit 传出。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L8–L11](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py#L8-L11), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L105–L107](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py#L105-L107), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L118–L130](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py#L118-L130), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L133–L134](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py#L133-L134) + + + + + +**依赖检测:Python 模块用 importlib 探测,CLI 工具用 shutil.which,字体依赖 fc-list** +check_py_deps 通过 importlib.import_module 逐个导入并读取 __version__(L51–L55);check_cli 用 shutil.which 查找可执行文件(L64–L71);check_cjk_font 在 fc-list 存在时调用 "fc-list :lang=zh family"(超时 20 秒)获取字体族(L77–L83)。若该调用抛出 Exception,会继续走 L86–L93 的回退扫描,因此单次 fc-list 失败不一定导致字体检查失败。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L50–L61](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py#L50-L61), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L64–L71](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py#L64-L71), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L74–L93](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py#L74-L93) + + + + + +**失败路径:模块导入抛 Exception 记录 pip 安装提示;字体未找到时记录诊断并计为必需失败** +导入失败时 except Exception 捕获,detail 写入 "missing (…); install: pip install <包名>"(L56–L61)。字体检查在 zh 查询无结果或抛异常且 fc-list 可用时,回退到全字体列表中按 CJK_FONT_HINTS 子串匹配(L86–L93);仍无结果则 ok=False、required=True,detail 提示安装 google-noto-sans-cjk-fonts 并警告中文将渲染为方框(L94–L101)。任一 required 项 ok=False 使 main 返回 1(L115–L116、L130)。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L56–L61](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py#L56-L61), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L86–L101](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py#L86-L101), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L115–L116](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py#L115-L116) + + + + + +**取舍:字体回退扫描用名称子串匹配,换取无 zh 元数据时的可用性,但不验证字形覆盖** +设计推断(非作者历史意图): + +推断:当 fc-list :lang=zh 无结果时,回退仅检查全字体列表是否包含 CJK_FONT_HINTS 中的名称子串(L88–L91),只要字体名命中即可通过(L94–L96)。好处是缺少语言元数据的系统仍能检出 CJK 字体;代价是该路径不确认字体实际覆盖中文字形。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L34–L37](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py#L34-L37), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L86–L96](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py#L86-L96) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-xlsx-formula-check.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-xlsx-formula-check.md new file mode 100644 index 00000000..9d461e0a --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-xlsx-formula-check.md @@ -0,0 +1,71 @@ +--- +title: "XLSX 公式静态校验(formula_check.py):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py:L27-L57, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py:L60-L79, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py:L17-L22, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py:L38-L40, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py:L9-L11, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py:L30-L30, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py:L24-L24, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py:L61-L71, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py:L67-L79, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py:L82-L83] +feature: "xlsx-formula-check" +entry_points: ["jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py"] +source_globs: ["jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py"] +--- + +# XLSX 公式静态校验(formula_check.py):实现深读 + +[功能概览](feature-xlsx-formula-check.md) · [owner 入口](_index.md) + + +**_scan 两遍读取工作簿并汇总 issue 列表** +_scan(path) 先以 data_only=True 只读加载工作簿,遍历所有工作表单元格,缓存值为字符串且包含任一 ERROR_TOKENS 时记录 {sheet, cell, type:"cached_error", detail};再以 data_only=False 只读加载一遍,对以 "=" 开头的公式文本做同样的 token 匹配并记录 type:"formula_error",最后返回 issue 列表。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py:L27–L57](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py#L27-L57) + + + + + +**main 的 CLI 契约:位置参数 file,--json/--report 布尔旗标,返回 0/1** +main() 用 argparse 接受一个位置参数 file 和 --json、--report 两个 store_true 旗标,返回 0(无 issue)或 1(有 issue);--json 时输出 {"ok":bool,"issues":[...]} 的缩进 JSON,否则打印 "OK: ..." 或逐条 "[type] sheet!cell -> detail" 文本。调用方需自行传入可被 openpyxl 加载的 xlsx 路径。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py:L60–L79](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py#L60-L79) + + + + + +**错误 token 列表硬编码,CLI 两个开关默认关闭,默认文本输出(在已展示的 argparse 解析器内)** +ERROR_TOKENS(#REF!、#DIV/0!、#VALUE!、#N/A、#NAME?、#NULL!、#NUM!)硬编码于 L24,所示解析器中没有覆盖它们的选项。--json 与 --report 为 store_true,默认 false;未传 --json 时输出人读文本(L69–L78)。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py:L24–L24](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py#L24-L24), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py:L61–L71](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py#L61-L71) + + + + + +**仅依赖 openpyxl,导入失败即打印并 sys.exit(2)** +脚本在模块顶层 try 导入 openpyxl 的 load_workbook 与 get_column_letter,任何异常都会向 stderr 打印 "openpyxl is required: ..." 并 sys.exit(2);get_column_letter 用于把列号转成字母拼出单元格地址。不依赖其他第三方库。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py:L17–L22](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py#L17-L22), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py:L38–L40](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py#L38-L40) + + + + + +**openpyxl 导入失败时打印 stderr 并 sys.exit(2);发现问题时 main 返回 1 并经 sys.exit(main()) 传播为进程退出码** +L17–L22 捕获导入 Exception,向 stderr 打印 "openpyxl is required: ..." 并 sys.exit(2)。L67–L79 中 issues 非空时 main 返回 1,L82–L83 的 __main__ 块以 sys.exit(main()) 将该返回值作为进程退出码。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py:L17–L22](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py#L17-L22), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py:L67–L79](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py#L67-L79), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py:L82–L83](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py#L82-L83) + + + + + +**只读静态扫描便宜但可能基于过期缓存值** +设计推断(非作者历史意图): + +(推断)收益:read_only=True 两遍加载 + 纯字符串 token 匹配,避免执行公式的开销与副作用;代价:docstring 明言不执行公式,cached_error 检查的是文件中缓存的值,若缓存过期则结果过期——需先运行 libreoffice_recalc.py 才能得到新鲜值。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py:L9–L11](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py#L9-L11), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py:L30–L30](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py#L30-L30) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-xlsx-insert-row.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-xlsx-insert-row.md new file mode 100644 index 00000000..293cf655 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-xlsx-insert-row.md @@ -0,0 +1,73 @@ +--- +title: "XLSX Row Insert with Range Extension:实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L60-L91, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L3-L20, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L50-L58, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L29-L36, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L53-L60, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L71-L78, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py:L96-L100, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py:L50-L54, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py:L50-L66, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L94-L95, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py:L154-L169, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L14-L20, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/SKILL.md:L97-L108, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/SKILL.md:L128-L144] +feature: "xlsx-insert-row" +entry_points: ["jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py"] +source_globs: ["jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py", "jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_shift_rows.py", "jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py"] +--- + +# XLSX Row Insert with Range Extension:实现深读 + +[功能概览](feature-xlsx-insert-row.md) · [owner 入口](_index.md) + + +**main():解析工作表,移位行,扩展范围,写入单元格,排序/更新维度/写入并打印** +main() 解析参数,解析工作表 XML(使用 --sheet 或第一个工作表),调用 X.shift_rows(sd, args.at, 1) 然后调用 X.extend_ranges(sd, args.at, 1),通过 get_or_make_row 在 --at 位置构建行,写入来自 --text/--values/--formula 的单元格(其中 {row} 被替换为 --at),然后 sort_sheetdata、update_dimension、write,并打印 "inserted row at N on 'S'";该函数局部返回 0。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L60–L91](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py#L60-L91) + + + + + +**CLI:位置参数 workdir,必填整数 --at,可选 --sheet/--text/--values/--formula/--copy-style-from** +接收一个解包后的工作簿目录(workdir)作为位置参数,--at 为必填整数;--text/--values/--formula 为 COL=VALUE 对(缺失 '=' 则通过 SystemExit 终止),公式中的 {row} 会被替换为 --at;输出直接写入工作表 XML,文档字符串指出需使用 xlsx_pack.py 重新打包,并在之后进行验证。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L3–L20](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py#L3-L20), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L50–L58](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py#L50-L58), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L29–L36](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py#L29-L36) + + + + + +**默认值:工作表回退至 first_sheet_name,pair 列表默认为 [],样式仅在 truthy --copy-style-from 时生效** +当省略 --sheet 时,工作表为 X.first_sheet_name(args.workdir)(workbook.xml 中的第一个 );--text/--values/--formula 默认为空列表;st_for(col) 返回 style_of(...) 仅当 args.copy_style_from 为 truthy 时,否则为 None,且 make_cell 仅在 style 不为 None 时设置 's' 属性。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L53–L60](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py#L53-L60), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L71–L78](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py#L71-L78), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py:L96–L100](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py#L96-L100), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py:L50–L54](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py#L50-L54) + + + + + +**通过 SystemExit 停止:格式错误的 COL=VALUE 对、没有工作表,以及未找到工作表** +parse_pairs 在任何没有 '=' 的项上引发 SystemExit("expected COL=VALUE, got: …");first_sheet_name 在 workbook.xml 没有工作表时引发 SystemExit("no sheets found in workbook.xml");resolve_worksheet 在名称不匹配任何工作表时引发 SystemExit("sheet not found: …")。这些错误通过 sys.exit(main()) 从正在运行的脚本中传播出来。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L29–L36](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py#L29-L36), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py:L50–L66](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py#L50-L66), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L94–L95](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py#L94-L95) + + + + + +**extend_ranges is best-effort: A1:B9-style totals ranges are bumped, single-cell refs are not** +设计推断(非作者历史意图): + +Benefit: the regex repl in extend_ranges bumps each range endpoint with row >= at by delta, so a totals-below SUM range keeps including the inserted row. Cost: it only rewrites two-cell ranges matching _RANGE — single-cell references are left untouched and the docstring says to validate totals afterwards. [inference: the benefit/cost framing within this implementation is my reading of the repl guard and module docstring.] + +来源:[jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py:L154–L169](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py#L154-L169), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L14–L20](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py#L14-L20) + + + + + +**Documented manual procedure for insert-row with post-save diff verification (NOT EXECUTED)** +文档中的人工验收步骤(本轮未执行): + +SKILL.md documents unpacking, running xlsx_insert_row.py with --at/--text/--values/--formula/--copy-style-from, then repacking with xlsx_pack.py; the EDIT rules require verifying the saved output with `xlsx_reader.py --diff-against input.xlsx` (confirming sheets, named ranges, pivots/macros, and sample data) before delivering. This is a documented procedure only; no automated test covering xlsx_insert_row.py appears in the offered evidence. + +来源:[jiuwenswarm/resources/agent/workspace/skills/xlsx/SKILL.md:L97–L108](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/SKILL.md#L97-L108), [jiuwenswarm/resources/agent/workspace/skills/xlsx/SKILL.md:L128–L144](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/SKILL.md#L128-L144) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-xlsx-reader-structural-diff.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-xlsx-reader-structural-diff.md new file mode 100644 index 00000000..434080bd --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-xlsx-reader-structural-diff.md @@ -0,0 +1,60 @@ +--- +title: "XLSX Read-Only Structure Reader and Edit-Damage Differ:实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L25-L29, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L32-L44, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L165-L178, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L199-L200, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L126-L141, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L67-L71, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L81-L101, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L126-L130, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L156-L196] +feature: "xlsx-reader-structural-diff" +entry_points: ["jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py"] +source_globs: ["jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py"] +--- + +# XLSX Read-Only Structure Reader and Edit-Damage Differ:实现深读 + +[功能概览](feature-xlsx-reader-structural-diff.md) · [owner 入口](_index.md) + + +**main() dispatches --diff-against to diff_against() and returns 0 only when report['ok']** +When --diff-against OLD is given, main() calls diff_against(args.file, OLD), prints JSON or a text report (issues prefixed '!', notes '.', up to 20 '~' changed-cell lines), and returns 0 if rep['ok'] else 1; main()'s return value is passed to sys.exit at module run. + +来源:[jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L165–L178](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py#L165-L178), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L199–L200](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py#L199-L200) + + + + + +**main() CLI: FILE plus --diff-against OLD.xlsx dispatch, returning 0/1 from the diff branch** +main() 接受位置参数 file、--sheet、--preview(默认 0)、--diff-against、--json。当 --diff-against 为真时调用 diff_against(args.file, args.diff_against),--json 打印缩进 JSON,否则打印 RESULT 与 issues/notes/前 20 条 changed_cells_sample,并在该分支内 return 0 if rep["ok"] else 1;仅当 --preview 和 --sheet 同时为真才调用 preview()。入口处 sys.exit(main())。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L156–L196](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py#L156-L196), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L199–L200](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py#L199-L200) + + + + + +**采样默认值:_sheet_sample 默认 max_sheets=50、max_cells=200,且限制的是保留的非空单元格数** +diff_against 调用 _sheet_sample 时不传参,使用默认 50/200;循环遍历所有行与列并跳过 None 值,仅在保留的非空单元格计数达到 max_cells 时提前 break,因此该默认不限制被扫描的单元格总数。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L81–L101](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py#L81-L101), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L126–L130](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py#L126-L130) + + + + + +**Depends on openpyxl (hard) and stdlib zipfile for feature detection** +If `from openpyxl import load_workbook` fails, the script prints 'openpyxl is required: ...' to stderr and exits 2. _zip_features instead reads the package with stdlib zipfile to detect vbaProject.bin, pivotTable/pivotCache names, xl/charts/ parts without openpyxl parsing. + +来源:[jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L25–L29](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py#L25-L29), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L32–L44](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py#L32-L44) + + + + + +**In diff mode, cell-sample exceptions become notes without clearing ok; preview() raises SystemExit on missing sheet** +diff_against wraps _sheet_sample calls in try/except: on exception it appends 'cell sample diff skipped: {e}' to report['notes'] and leaves report['ok'] unchanged. Separately, preview() raises SystemExit('sheet not found: ...; available: ...') when the requested sheet is absent — a preview-mode failure, not part of the diff branch. + +来源:[jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L126–L141](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py#L126-L141), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L67–L71](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py#L67-L71) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-xlsx-workbook-unpack-repack.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-xlsx-workbook-unpack-repack.md new file mode 100644 index 00000000..b5ec682c --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-xlsx-workbook-unpack-repack.md @@ -0,0 +1,80 @@ +--- +title: "XLSX Skill Format-Preserving Unpack/Repack:实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_unpack.py:L16-L38, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_pack.py:L30-L54, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_pack.py:L22-L27, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_pack.py:L47-L52, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_unpack.py:L3-L13, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_pack.py:L3-L19, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_unpack.py:L17-L23, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_pack.py:L31-L47, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_pack.py:L48-L52, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_pack.py:L8-L15, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/SKILL.md:L100-L105] +feature: "xlsx-workbook-unpack-repack" +entry_points: ["jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_pack.py", "jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_unpack.py"] +source_globs: ["jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_pack.py", "jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_unpack.py"] +--- + +# XLSX Skill Format-Preserving Unpack/Repack:实现深读 + +[功能概览](feature-xlsx-workbook-unpack-repack.md) · [owner 入口](_index.md) + + +**Unpack extracts workbook ZIP parts, then pack walks the dir and rewrites a sorted ZIP** +xlsx_unpack.py main() 校验 argv 长度与 zipfile.is_zipfile 后 extractall 到 outdir 并打印 part 数及 VBA/pivot/chart 提示;xlsx_pack.py main() 用 os.walk 收集文件为 arc 名,按 _order_key 排序([Content_Types].xml 首位、_rels/ 次之),逐个写入输出 ZIP,vbaProject.bin 用 ZIP_STORED 其余 ZIP_DEFLATED,最后打印 packed N parts 并 return 0。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_unpack.py:L16–L38](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_unpack.py#L16-L38), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_pack.py:L30–L54](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_pack.py#L30-L54) + + + + + +**Both scripts take exactly two positional argv paths; wrong argc returns 2, ZIP/dir checks return 1** +`xlsx_unpack.py INPUT.xlsx OUTDIR/` 先用 `zipfile.is_zipfile` 校验输入,再 `extractall` 到(必要时创建的)目录,并打印解包的部件数;仅当存在 `xl/vbaProject.bin`、pivotTable 或 `xl/charts/` 部件时额外打印 NOTE。`xlsx_pack.py SRCDIR/ OUTPUT.xlsx` 要求 SRCDIR 是目录,遍历后按 `_order_key` 排序写入输出 ZIP 并打印 `packed N parts`,随后 `return 0`(main 内返回,非进程退出码断言)。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_unpack.py:L16–L38](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_unpack.py#L16-L38), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_pack.py:L30–L54](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_pack.py#L30-L54) + + + + + +**No configurable settings; entry ordering and compression are hardcoded** +两个脚本均无配置项或环境变量:入口顺序由 _order_key 硬编码([Content_Types].xml → (0,arc)、_rels/ → (1,arc)、其余 (2,arc)),压缩方式仅由文件名后缀 vbaProject.bin 决定 ZIP_STORED,否则 ZIP_DEFLATED。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_pack.py:L22–L27](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_pack.py#L22-L27), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_pack.py:L47–L52](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_pack.py#L47-L52) + + + + + +**Depends only on Python stdlib (os, sys, zipfile), avoiding openpyxl round-trips** +两个脚本仅 import os/sys/zipfile,把 .xlsx 当 ZIP of XML parts 处理;模块 docstring 说明这是 openpyxl 往返的 format-preserving 替代方案,vbaProject.bin 以未压缩存储保持宏有效。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_unpack.py:L3–L13](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_unpack.py#L3-L13), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_pack.py:L3–L19](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_pack.py#L3-L19) + + + + + +**Usage error returns 2; non-zip input or missing srcdir returns 1 with stderr message** +unpack: `len(sys.argv)!=3` → stderr usage、return 2;`not zipfile.is_zipfile(src)` → stderr "not a valid xlsx/zip: src"、return 1。pack: 目录不存在 → stderr "not a directory: srcdir"、return 1;若收集的 arcs 缺 [Content_Types].xml 仅打印 WARNING 到 stderr 仍继续打包(return 0)。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_unpack.py:L17–L23](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_unpack.py#L17-L23), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_pack.py:L31–L47](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_pack.py#L31-L47) + + + + + +**Pack keeps vbaProject.bin stored uncompressed but shifts sharedStrings/calcChain repair to the caller** +Benefit (documented intent): xlsx_pack.py writes parts ending in vbaProject.bin with ZIP_STORED and all others deflated so macros stay valid. Cost (documented): pack does NOT recompute sharedStrings counts or rebuild calcChain — the caller must edit those in the unpacked dir or run libreoffice_recalc.py for formula cells without a cached . Inference: storing the macro blob uncompressed can enlarge the output file relative to deflating it. + +来源:[jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_pack.py:L48–L52](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_pack.py#L48-L52), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_pack.py:L8–L15](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_pack.py#L8-L15) + + + + + +**Documented manual EDIT verification: xlsx_reader.py --diff-against the input (NOT EXECUTED here)** +文档中的人工验收步骤(本轮未执行): + +SKILL.md EDIT rule 5 directs running xlsx_reader.py output.xlsx --diff-against input.xlsx after packing and confirming original sheet names, named ranges, pivots/macros, and a sample of original data before delivery; a failed check must be fixed before delivering. This is a documented procedure only — it was not executed and no automated runtime or source-text test for this feature is shown. + +来源:[jiuwenswarm/resources/agent/workspace/skills/xlsx/SKILL.md:L100–L105](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/SKILL.md#L100-L105) + + + diff --git a/knowledge/repos/jiuwenswarm/components/extensions-plugins/feature-depth-agentos-sandbox-create-lifecycle.md b/knowledge/repos/jiuwenswarm/components/extensions-plugins/feature-depth-agentos-sandbox-create-lifecycle.md new file mode 100644 index 00000000..90682276 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/extensions-plugins/feature-depth-agentos-sandbox-create-lifecycle.md @@ -0,0 +1,62 @@ +--- +title: "AgentOS 沙箱创建与幂等对账:实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/agentos/agentos_router/registry_client.py:L338-L339, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/agentos/agentos_router/registry_client.py:L495-L535, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/agentos/agentos_router/stale_cleanup.py:L22-L53, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/agentos/agentos_router/agent_manager.py:L406-L412, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/agentos/agentos_router/agent_manager.py:L507-L534, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/agentos/agentos_router/stale_cleanup.py:L61-L78, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/extensions/test_agentos_agent_manager.py:L127-L141] +feature: "agentos-sandbox-create-lifecycle" +entry_points: ["jiuwenswarm/extensions/agentos/agentos_router/router_client.py"] +source_globs: ["jiuwenswarm/extensions/agentos/agentos_router/router_client.py", "jiuwenswarm/extensions/agentos/agentos_router/agent_manager.py", "jiuwenswarm/extensions/agentos/agentos_router/config.py", "jiuwenswarm/extensions/agentos/agentos_router/stale_cleanup.py"] +--- + +# AgentOS 沙箱创建与幂等对账:实现深读 + +[功能概览](feature-agentos-sandbox-create-lifecycle.md) · [owner 入口](_index.md) + + +**RegistryClient.enabled 由 _base_url 决定,禁用时 list_instances 回退到本地 _registered_agents** +enabled 即 bool(self._base_url)。list_instances 在 not self.enabled 时不发 GET api/instances,而是把 _registered_agents 中的 info 转成 InstanceRecord 并用 _instance_matches 按 node/framework/kind/user/include_unhealthy 过滤后返回。 + +来源:[jiuwenswarm/extensions/agentos/agentos_router/registry_client.py:L338–L339](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/agentos/agentos_router/registry_client.py#L338-L339), [jiuwenswarm/extensions/agentos/agentos_router/registry_client.py:L495–L535](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/agentos/agentos_router/registry_client.py#L495-L535) + + + + + +**cleanup_stale_sandboxes 依赖注入 YuanRong、Registry、AgentManager,registry.enabled 关闭即返回 0** +该函数以关键字参数注入 YuanrongFrontendAgentClient、RegistryClient 与 AgentManager;当 registry.enabled 为假时直接返回 0,不发起 list_instances,实例列举经由 registry.list_instances(include_unhealthy=True)。 + +来源:[jiuwenswarm/extensions/agentos/agentos_router/stale_cleanup.py:L22–L53](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/agentos/agentos_router/stale_cleanup.py#L22-L53) + + + + + +**等待创建时按状态抛 AgentCreatingTimeout/AgentDeleted/AgentCreateFailed;_mark_creator_failed 仅作用于仍是 owner 的 runtime** +创建等待路径在超时(含 AGENT_CREATING_TIMEOUT 消息)、runtime.is_deleted()、is_failed() 时分别抛 AgentCreatingTimeout、AgentDeleted、AgentCreateFailed。_mark_creator_failed 在锁内确认 _runtimes.get(key) 仍是 owner_runtime 才 mark_failed;对 asyncio.CancelledError 只记 WARNING 日志并直接 return,不 logger.exception。 + +来源:[jiuwenswarm/extensions/agentos/agentos_router/agent_manager.py:L406–L412](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/agentos/agentos_router/agent_manager.py#L406-L412), [jiuwenswarm/extensions/agentos/agentos_router/agent_manager.py:L507–L534](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/agentos/agentos_router/agent_manager.py#L507-L534) + + + + + +**清理循环逐条容错:单条失败不中断,但返回值只计尝试数** +设计推断(非作者历史意图): + +收益:单条 _cleanup_one 异常仅 logger.exception 后继续处理其余记录,启动期清理不会因一行坏数据而中断;代价(推断):processed 统计的是尝试条数而非成功销毁数,调用方无法从返回值区分部分失败。is_closed 回调为真时提前 break。 + +来源:[jiuwenswarm/extensions/agentos/agentos_router/stale_cleanup.py:L61–L78](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/agentos/agentos_router/stale_cleanup.py#L61-L78) + + + + + +**test_agent_manager_get_delete_and_list 运行时验证 get/删除/列举契约** +该 asyncio 测试先 get_or_create_agent("u1","jiuwenswarm"),断言 get_agent 返回的快照 info 与 created.info 相等且 list_user_agents 含该 agent_id;随后 delete_agent 并断言 get_agent 返回 None、list_user_agents 为空列表。断言覆盖 AgentManager 本身,属 helper 级运行时验证。 + +来源:[tests/unit_tests/extensions/test_agentos_agent_manager.py:L127–L141](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/extensions/test_agentos_agent_manager.py#L127-L141) + + + diff --git a/knowledge/repos/jiuwenswarm/components/extensions-plugins/feature-depth-video-agent-managed-task-service.md b/knowledge/repos/jiuwenswarm/components/extensions-plugins/feature-depth-video-agent-managed-task-service.md new file mode 100644 index 00000000..595124e9 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/extensions-plugins/feature-depth-video-agent-managed-task-service.md @@ -0,0 +1,71 @@ +--- +title: "Voice/Video Duplex Managed Agent Task Service (Durable Queue, Concurrency, Uncertainty Semantics):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/backend/tasks/service.py:L183-L210, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/backend/tasks/service.py:L491-L533, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/tests/backend/test_managed_tasks.py:L69-L84, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/backend/tasks/service.py:L79-L113, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/backend/task_adapter.py:L283-L293, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/backend/tasks/service.py:L582-L591] +feature: "video-agent-managed-task-service" +entry_points: ["jiuwenswarm/extensions/video_duplex/backend/tasks/service.py"] +source_globs: ["jiuwenswarm/extensions/video_duplex/backend/tasks/service.py", "jiuwenswarm/extensions/video_duplex/backend/tasks/rail.py"] +--- + +# Voice/Video Duplex Managed Agent Task Service (Durable Queue, Concurrency, Uncertainty Semantics):实现深读 + +[功能概览](feature-video-agent-managed-task-service.md) · [owner 入口](_index.md) + + +**kick() dispatches queued tasks up to concurrency after an immediate transaction snapshot** +When started and not closed, kick() reads all tasks in one store transaction, collects active ones (running/cancelling/unknown/waiting_user or already having a worker), then iterates tasks by position: once the count of active tasks that are not unknown and not settled waiting_user reaches self.concurrency it breaks; queued tasks not already in self.workers and passing _ready get an asyncio.create_task(self._drain(id)) worker registered in self.workers with a _worker_done callback. + +来源:[jiuwenswarm/extensions/video_duplex/backend/tasks/service.py:L79–L113](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/video_duplex/backend/tasks/service.py#L79-L113) + + + + + +**submit input contract: strict ValueError validation before persistence** +submit(owner, session, command_id, instruction, request=None) requires a string owner, non-empty session, non-blank instruction ≤16000 chars, boolean independent, and depends_on/resources lists ≤32 entries of non-blank strings ≤256 chars; violations raise ValueError. + +来源:[jiuwenswarm/extensions/video_duplex/backend/tasks/service.py:L183–L210](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/video_duplex/backend/tasks/service.py#L183-L210) + + + + + +**VideoSearchManager.service lazily builds TaskService with self.concurrency and a derived notification_timeout** +On first access the service property constructs TaskService(TaskStore(self.path or task_database()), AgentTaskExecutor(...), on_change=self.changed, concurrency=self.concurrency, notification_timeout=AGENT_QUERY_TIMEOUT + 2 * EVENT_SEND_TIMEOUT + 1), caching it in self._service. The shown lines do not establish defaults for self.concurrency or the timeout constants. + +来源:[jiuwenswarm/extensions/video_duplex/backend/task_adapter.py:L283–L293](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/video_duplex/backend/task_adapter.py#L283-L293) + + + + + +**answer() rejects stale questions and marks failed executor answers unknown** +answer raises ValueError("Question is no longer pending for this task") unless status is waiting_user with a matching pending interaction id; if executor.answer throws, it sets status="unknown" with the error (only while still running with same request_id) and re-raises. + +来源:[jiuwenswarm/extensions/video_duplex/backend/tasks/service.py:L491–L533](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/video_duplex/backend/tasks/service.py#L491-L533) + + + + + +**Latest-snapshot-only notifications avoid client backpressure at the cost of coalescing updates** +设计推断(非作者历史意图): + +_notify stores only the newest task snapshot per task id (pending_notifications[key] = task) and runs a single sender task per key; the comment states slow clients must not backpressure agent output or grow an unbounded queue. Inferred cost: intermediate snapshots between sends are overwritten, so a client may never see them. + +来源:[jiuwenswarm/extensions/video_duplex/backend/tasks/service.py:L582–L591](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/video_duplex/backend/tasks/service.py#L582-L591) + + + + + +**Runtime test: retry dedup, conflict ValueError, owner/session scoping** +test_retry_conflict_scope_and_cancel_before_dispatch asserts submit with the same command_id and text returns the same id, differing text raises ValueError, wrong owner/session get/cancel raise ValueError, and cancel before dispatch never reaches the executor. NOT EXECUTED here. + +来源:[jiuwenswarm/extensions/video_duplex/tests/backend/test_managed_tasks.py:L69–L84](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/video_duplex/tests/backend/test_managed_tasks.py#L69-L84) + + + diff --git a/knowledge/repos/jiuwenswarm/components/extensions-plugins/feature-depth-yuanrong-agent-file-transfer.md b/knowledge/repos/jiuwenswarm/components/extensions-plugins/feature-depth-yuanrong-agent-file-transfer.md new file mode 100644 index 00000000..2d6d6c39 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/extensions-plugins/feature-depth-yuanrong-agent-file-transfer.md @@ -0,0 +1,60 @@ +--- +title: "YuanRong Agent 容器文件上传/下载/列举/建目录:实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/yuanrong_frontend_client.py:L1304-L1332, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/yuanrong_frontend_client.py:L1315-L1324, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/container_file_http.py:L618-L626, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/yuanrong_frontend_client.py:L1333-L1369, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/extensions/test_yuanrong_frontend_client.py:L1171-L1183, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/yuanrong_frontend_client.py:L924-L967] +feature: "yuanrong-agent-file-transfer" +entry_points: ["jiuwenswarm/extensions/yuanrong_frontend_client.py"] +source_globs: ["jiuwenswarm/extensions/yuanrong_frontend_client.py", "jiuwenswarm/gateway/channel_manager/web/container_file_http.py"] +--- + +# YuanRong Agent 容器文件上传/下载/列举/建目录:实现深读 + +[功能概览](feature-yuanrong-agent-file-transfer.md) · [owner 入口](_index.md) + + +**mkdir_agent_dir:strip 校验、NUL 仅查 path 后经 asyncio.to_thread 发送并解析** +调用 mkdir_agent_dir 后先 _ensure_connected,将 instance_id 与 path 各自 strip 并在为空时抛 ValueError;随后仅对 normalized_path 检查 "\x00",命中则抛 http_status=400、error_code=BAD_REQUEST 的 YuanrongAgentFileError。通过后经 _normalize_mkdir_mode 规整 mode,bind_southbound_trace_id 绑定 trace,asyncio.to_thread 调 _do_agent_file_mkdir 发送请求,并把 body/status/normalized_path 交给 _parse_agent_file_mkdir_response 返回 dict。 + +来源:[jiuwenswarm/extensions/yuanrong_frontend_client.py:L924–L967](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/yuanrong_frontend_client.py#L924-L967) + + + + + +**_do_agent_file_download 以带 Range 头的同步 GET 返回 (status, data, content_type, total_size)** +对 _agent_files_download_url 发 GET,头含 Accept: */*、合并后的 auth 头与 bytes={offset}-{end} Range;成功路径读取响应体并从 Content-Range 解析 total_size(回退 offset+Content-Length),把状态、数据、类型与总大小打包返回给调用方处理。 + +来源:[jiuwenswarm/extensions/yuanrong_frontend_client.py:L1304–L1332](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/yuanrong_frontend_client.py#L1304-L1332) + + + + + +**文件下载直接依赖 urllib.request 同步 HTTP,web 层依赖 client.download_container_file** +_do_agent_file_download 内联使用 urllib.request.urlopen 完成 HTTP;后果是每次块下载为同步阻塞调用。raw_file_get 通过闭包 _one_chunk 调用 client.download_container_file,并以 AgentOSFileTransferError 作为可识别的错误契约分支。 + +来源:[jiuwenswarm/extensions/yuanrong_frontend_client.py:L1315–L1324](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/yuanrong_frontend_client.py#L1315-L1324), [jiuwenswarm/gateway/channel_manager/web/container_file_http.py:L618–L626](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/channel_manager/web/container_file_http.py#L618-L626) + + + + + +**下载 HTTPError 不抛出而返回错误状态元组;超时抛 YuanrongAgentApiError,416 降级为 info 日志** +HTTPError 分支读取错误体并返回 (status, body, content_type, total_size) 交由上层判定,仅记录日志(status==416 用 info,其余 error);其他异常中若 _is_timeout_error 命中则抛 YuanrongAgentApiError("file download timeout after {resolved_timeout}s"),否则返回 500 状态元组。 + +来源:[jiuwenswarm/extensions/yuanrong_frontend_client.py:L1333–L1369](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/yuanrong_frontend_client.py#L1333-L1369) + + + + + +**运行时测试覆盖空路径与 NUL 路径的本地拒绝分支** +test_mkdir_agent_dir_rejects_empty_path 断言 path 为空白时抛出 match="path is required" 的 ValueError;test_mkdir_agent_dir_rejects_nul_path 断言含 \x00 的 path 抛出 YuanrongAgentFileError 且 error_code == "BAD_REQUEST"。此为已存在的自动化运行时用例,此处未执行。 + +来源:[tests/unit_tests/extensions/test_yuanrong_frontend_client.py:L1171–L1183](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/extensions/test_yuanrong_frontend_client.py#L1171-L1183) + + + diff --git a/knowledge/repos/jiuwenswarm/components/extensions-plugins/feature-depth-yuanrong-faas-invocation.md b/knowledge/repos/jiuwenswarm/components/extensions-plugins/feature-depth-yuanrong-faas-invocation.md new file mode 100644 index 00000000..a7801174 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/extensions-plugins/feature-depth-yuanrong-faas-invocation.md @@ -0,0 +1,42 @@ +--- +title: "YuanRong FaaS 函数调用(非流式 + SSE 流式):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/yuanrong_frontend_client.py:L1880-L1908, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/agent_client/extension.py:L31-L60, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/yuanrong_frontend_client.py:L969-L971, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/yuanrong_frontend_client.py:L1936-L1943] +feature: "yuanrong-faas-invocation" +entry_points: ["jiuwenswarm/extensions/yuanrong_frontend_client.py"] +source_globs: ["jiuwenswarm/extensions/yuanrong_frontend_client.py", "jiuwenswarm/extensions/clawee.py", "jiuwenswarm/extensions/agent_client/extension.py"] +--- + +# YuanRong FaaS 函数调用(非流式 + SSE 流式):实现深读 + +[功能概览](feature-yuanrong-faas-invocation.md) · [owner 入口](_index.md) + + +**send_request_stream 输入 E2AEnvelope、产出 AgentResponseChunk;error 项产出错误块,exception 项抛 RuntimeError** +输入是 E2AEnvelope;产出为 AgentResponseChunk,request_id/channel_id 优先取 chunk 自身字段、兜底 e2a_to_agent_request 的值。"error" 项产出 payload={"error": text or "invoke stream failed"} 且 is_complete=False 的块;"exception" 项直接 raise RuntimeError(f"invoke stream failed: {text}")。调用方需消费异步迭代器并在 RuntimeError 上做自身错误处理。 + +来源:[jiuwenswarm/extensions/yuanrong_frontend_client.py:L1880–L1908](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/yuanrong_frontend_client.py#L1880-L1908) + + + + + +**gateway.agent_client.type=yuanrong 时必填两项,其余有默认值** +type 默认 "websocket"(非 yuanrong 返回 [] 不注册);yuanrong 模式下 frontend_endpoint 与 function_version_urn 缺失抛 ValueError;concurrency 默认 1、invoke_timeout_s 默认 60.0、agent_timeout_s 默认 300.0、agent_namespace 默认 "default"。 + +来源:[jiuwenswarm/extensions/agent_client/extension.py:L31–L60](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/agent_client/extension.py#L31-L60) + + + + + +**未连接时抛 RuntimeError("client not connected");流式 HTTP 非 2xx 转为队列 error 项** +_ensure_connected 在 self._connected 为假时抛 RuntimeError("client not connected");_do_invoke_stream 中 200<=status<300 不成立时读取响应体、记录日志并把 ("error", 含 http_status 与 body 的 JSON) 经 call_soon_threadsafe 放入输出队列后 return——return 只结束该线程函数,不表示进程退出。 + +来源:[jiuwenswarm/extensions/yuanrong_frontend_client.py:L969–L971](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/yuanrong_frontend_client.py#L969-L971), [jiuwenswarm/extensions/yuanrong_frontend_client.py:L1936–L1943](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/yuanrong_frontend_client.py#L1936-L1943) + + + diff --git a/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-at-file-reference-inlining-b1a822e1.md b/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-at-file-reference-inlining-b1a822e1.md new file mode 100644 index 00000000..38617f3c --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-at-file-reference-inlining-b1a822e1.md @@ -0,0 +1,82 @@ +--- +title: "@path 文件引用内联与 @agent 提及解析:实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/message_handler/message_handler.py:L2909-L2915, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/gateway/test_at_file_references.py:L20-L22, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/gateway/test_at_file_references.py:L9-L13, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/gateway/test_at_file_references.py:L177-L180, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/message_handler/message_handler.py:L2846-L2866, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/message_handler/message_handler.py:L2882-L2908, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/message_handler/message_handler.py:L2846-L2871, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/message_handler/message_handler.py:L2873-L2915] +feature: "at-file-reference-inlining-b1a822e1" +entry_points: ["jiuwenswarm/gateway/message_handler/message_handler.py"] +source_globs: ["jiuwenswarm/gateway/message_handler/message_handler.py"] +--- + +# @path 文件引用内联与 @agent 提及解析:实现深读 + +[功能概览](feature-at-file-reference-inlining-b1a822e1.md) · [owner 入口](_index.md) + + +**pattern.sub 对 content 中的 @path 匹配逐个替换为 file-content 包裹的文件文本** +对传入 content 执行 pattern.sub:每个匹配成功读取的文件被替换为 '\n\n{text}\n\n';本切片未显示 pattern 构造与读取主体(2906 之前)。 + +来源:[jiuwenswarm/gateway/message_handler/message_handler.py:L2909–L2915](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/message_handler/message_handler.py#L2909-L2915) + + + + + +**静态方法 resolve_at_file_references(content, cwd=None, max_file_size=_DEFAULT_INLINE_FILE_SIZE_LIMIT) -> str** +Empty content returns as-is. Matched non-agent @path/@"quoted" refs (after #L... suffix strip, ~/ expand, cwd/absolute resolution) that resolve to an existing file are replaced by a block; only when max_file_size is None is the whole file read — otherwise reading is capped and oversized files get a truncation suffix. Non-files, OSError/UnicodeDecodeError, and raw values starting agent-/agent: keep the original match. Caller supplies content and optionally cwd; default cwd is os.getcwd(). + +来源:[jiuwenswarm/gateway/message_handler/message_handler.py:L2846–L2871](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/message_handler/message_handler.py#L2846-L2871), [jiuwenswarm/gateway/message_handler/message_handler.py:L2873–L2915](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/message_handler/message_handler.py#L2873-L2915) + + + + + +**max_file_size 默认 _DEFAULT_INLINE_FILE_SIZE_LIMIT;None 读全文,否则截断加尾注** +参数 max_file_size 默认值为模块常量 _DEFAULT_INLINE_FILE_SIZE_LIMIT(2850,具体数值未在所示片段中给出)。max_file_size 为 None 时整文件读取(2897-2898);否则读取 max_file_size+1 字符并在超出时截断到 max_file_size,追加 '... (truncated, original_size=N bytes)' 尾注(2900-2908)。相对路径按 cwd(缺省 os.getcwd(),2866)拼接,~/ 前缀展开到用户主目录(2883-2889)。 + +来源:[jiuwenswarm/gateway/message_handler/message_handler.py:L2846–L2866](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/message_handler/message_handler.py#L2846-L2866), [jiuwenswarm/gateway/message_handler/message_handler.py:L2882–L2908](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/message_handler/message_handler.py#L2882-L2908) + + + + + +**路径解析以调用方提供的 cwd 为基准(测试用 os.path.basename/dirname 构造)** +设计推断(非作者历史意图): + +测试把消息中的引用写成 basename,并把 cwd 设为 dirname,说明文件解析依赖调用方传入的工作目录而非固定根;这是从测试构造推断的耦合,实现在所提供的切片中不可见。 + +来源:[tests/unit_tests/gateway/test_at_file_references.py:L20–L22](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/gateway/test_at_file_references.py#L20-L22) + + + + + +**文件读取触发 OSError 或 UnicodeDecodeError 时返回原始匹配串 m.group(0),异常不外传** +读取文件的 try 块捕获 (OSError, UnicodeDecodeError) 后返回 m.group(0),即该 @path 引用原文保留在 content 中,替换静默跳过;其他异常路径未在切片中显示。 + +来源:[jiuwenswarm/gateway/message_handler/message_handler.py:L2909–L2915](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/message_handler/message_handler.py#L2909-L2915) + + + + + +**内联换取自包含,代价是消息体膨胀(依据测试文档字符串推断)** +设计推断(非作者历史意图): + +测试类文档字符串称 @path → 内联:收益是代理无需文件系统访问即可看到内容;成本是文件内容进入消息文本,体积随文件增长。此为基于文档字符串与命名的推断。 + +来源:[tests/unit_tests/gateway/test_at_file_references.py:L9–L13](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/gateway/test_at_file_references.py#L9-L13) + + + + + +**助手级单测:直接断言无 @ 输入原样返回** +test_no_at_symbol_returns_unchanged 直接调用 MessageHandler.resolve_at_file_references 并断言返回 "hello world";断言仅覆盖助手本身,非网关消息链路的运行时集成。内联与 strip 用例的断言行未在提供切片内。 + +来源:[tests/unit_tests/gateway/test_at_file_references.py:L177–L180](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/gateway/test_at_file_references.py#L177-L180) + + + diff --git a/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-channel-security-review-slash-command.md b/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-channel-security-review-slash-command.md new file mode 100644 index 00000000..add14dc5 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-channel-security-review-slash-command.md @@ -0,0 +1,71 @@ +--- +title: "/security-review 安全审查斜杠命令与 git 预执行:实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/message_handler/prompts/security_review_prompt.py:L243-L255, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/gateway/test_message_handler_security_review_prompt.py:L48-L56, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/gateway/test_message_handler_security_review_prompt.py:L28-L39, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/message_handler/prompts/security_review_prompt.py:L14-L22, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/message_handler/prompts/security_review_prompt.py:L39-L45, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/message_handler/prompts/security_review_prompt.py:L14-L17, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/message_handler/prompts/security_review_prompt.py:L48-L60, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/gateway/test_message_handler_security_review_prompt.py:L136-L141, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/message_handler/prompts/security_review_prompt.py:L10-L11, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/message_handler/prompts/security_review_prompt.py:L63-L72, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/message_handler/prompts/security_review_prompt.py:L5-L7, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/message_handler/message_handler.py:L52-L56] +feature: "channel-security-review-slash-command" +entry_points: ["jiuwenswarm/gateway/message_handler/message_handler.py", "jiuwenswarm/gateway/message_handler/prompts/security_review_prompt.py"] +source_globs: ["jiuwenswarm/gateway/message_handler/message_handler.py", "jiuwenswarm/gateway/message_handler/prompts/security_review_prompt.py"] +--- + +# /security-review 安全审查斜杠命令与 git 预执行:实现深读 + +[功能概览](feature-channel-security-review-slash-command.md) · [owner 入口](_index.md) + + +**_build_inlined_intro 接收 git_outputs 字典;GitPreExecError 表示单条只读 git 命令非零退出的中止** +_build_inlined_intro(git_outputs: dict[str, str]) -> str 以标签到命令输出的映射为入参返回 intro 字符串(可见片段只展示到循环开头,未见访问 git_outputs 具体键的行)。GitPreExecError(Exception) 的 docstring 定义为“某条只读 git 命令非零退出 —— 预执行失败的中止语义”。 + +来源:[jiuwenswarm/gateway/message_handler/prompts/security_review_prompt.py:L10–L11](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/message_handler/prompts/security_review_prompt.py#L10-L11), [jiuwenswarm/gateway/message_handler/prompts/security_review_prompt.py:L63–L72](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/message_handler/prompts/security_review_prompt.py#L63-L72) + + + + + +**输出语言由 config 的 preferred_language 决定;cwd 缺省 None 回退指令式 prompt** +输出语言读取 get_config() 的 `preferred_language`(如 "en"→`Respond in English.`,"zh"→`Respond in Chinese (simplified).`);cwd 参数缺省 None,此时退回旧的“指令式” prompt(让 LLM 自己跑 git),行为不变。 + +来源:[jiuwenswarm/gateway/message_handler/prompts/security_review_prompt.py:L243–L255](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/message_handler/prompts/security_review_prompt.py#L243-L255), [tests/unit_tests/gateway/test_message_handler_security_review_prompt.py:L48–L56](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/gateway/test_message_handler_security_review_prompt.py#L48-L56), [tests/unit_tests/gateway/test_message_handler_security_review_prompt.py:L28–L39](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/gateway/test_message_handler_security_review_prompt.py#L28-L39) + + + + + +**security_review_prompt.py 依赖 subprocess 与 response_language_line;MessageHandler 导入其 GitPreExecError 与 build_security_review_prompt** +模块 import subprocess(预执行 git 的进程机制)并从 jiuwenswarm.gateway.message_handler.prompts 引入 response_language_line;message_handler.py L53–L56 显式导入 GitPreExecError 与 build_security_review_prompt,把预执行失败异常类型与 prompt 构建函数耦合进 MessageHandler。调 subprocess 实际运行 git 的调用点不在已展示行内。 + +来源:[jiuwenswarm/gateway/message_handler/prompts/security_review_prompt.py:L5–L7](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/message_handler/prompts/security_review_prompt.py#L5-L7), [jiuwenswarm/gateway/message_handler/message_handler.py:L52–L56](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/message_handler/message_handler.py#L52-L56) + + + + + +**git 非零退出触发受保护分支:抛 GitPreExecError 携带命令、退出码与 stderr** +subprocess.run 返回后先检查 result.returncode != 0,命中即 raise GitPreExecError(f"git {args} failed (exit {code}): {stderr.strip()}"),该条及后续命令输出不再写入 outputs;异常向上传播,本片段内无捕获。注释注明仅 origin/HEAD 未设置、无共同历史等真失败才非零。 + +来源:[jiuwenswarm/gateway/message_handler/prompts/security_review_prompt.py:L14–L22](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/message_handler/prompts/security_review_prompt.py#L14-L22), [jiuwenswarm/gateway/message_handler/prompts/security_review_prompt.py:L39–L45](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/message_handler/prompts/security_review_prompt.py#L39-L45) + + + + + +**取舍:预执行内联真实 git 输出,但分支无仓库上下文时退回让 LLM 自己跑 git 的指令式提示** +设计推断(非作者历史意图): + +收益(推理):有 cwd 时把四段真实仓库状态内联进提示词,模型无需自行执行命令、结果确定。成本(推理):无仓库上下文(cwd=None,如单测)时使用 _SECURITY_REVIEW_INTRO_FALLBACK 的旧指令式措辞,把执行 git 的负担和不确定性交回 LLM。此取舍由源码注释直接陈述。 + +来源:[jiuwenswarm/gateway/message_handler/prompts/security_review_prompt.py:L14–L17](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/message_handler/prompts/security_review_prompt.py#L14-L17), [jiuwenswarm/gateway/message_handler/prompts/security_review_prompt.py:L48–L60](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/message_handler/prompts/security_review_prompt.py#L48-L60) + + + + + +**单测运行时断言 prompt 文本、语言切换与 git 失败中止** +tests/unit_tests/gateway/test_message_handler_security_review_prompt.py 实际调用 build_security_review_prompt 并断言:cwd=None 时含 `` `git status` `` 等指令且无 `Additional instructions:`(28-39 行);zh 配置输出 `Respond in Chinese (simplified).`(48-56 行);无 origin/HEAD 的仓库抛 GitPreExecError(136-141 行)。这些断言覆盖 prompt 构建函数本身,未覆盖斜杠命令的完整频道链路。 + +来源:[tests/unit_tests/gateway/test_message_handler_security_review_prompt.py:L28–L39](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/gateway/test_message_handler_security_review_prompt.py#L28-L39), [tests/unit_tests/gateway/test_message_handler_security_review_prompt.py:L48–L56](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/gateway/test_message_handler_security_review_prompt.py#L48-L56), [tests/unit_tests/gateway/test_message_handler_security_review_prompt.py:L136–L141](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/gateway/test_message_handler_security_review_prompt.py#L136-L141) + + + diff --git a/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-gateway-config-hot-reload.md b/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-gateway-config-hot-reload.md new file mode 100644 index 00000000..ecdc88ae --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-gateway-config-hot-reload.md @@ -0,0 +1,62 @@ +--- +title: "Gateway Config-Save Hot Reload (agent.reload_config retry, restart fallback, browser/proactive side effects):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L3205-L3254, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L3205-L3242, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L3211-L3241, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L3211-L3242, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L3197-L3216] +feature: "gateway-config-hot-reload" +entry_points: ["jiuwenswarm/gateway/app_gateway.py"] +source_globs: ["jiuwenswarm/gateway/app_gateway.py"] +--- + +# Gateway Config-Save Hot Reload (agent.reload_config retry, restart fallback, browser/proactive side effects):实现深读 + +[功能概览](feature-gateway-config-hot-reload.md) · [owner 入口](_index.md) + + +**_schedule_channel_config_retry spawns a background _retry task that reapplies a failed channel config** +调用 _schedule_channel_config_retry 后创建名为 initial-channel-retry- 的 asyncio 任务:_retry 先 sleep 2.0s,若 channel_manager.get_conf_revision 仍等于 expected_revision 就 await set_conf 重放快照;成功记日志并 return,任务完成后从 channel_retry_tasks 集合移除。 + +来源:[jiuwenswarm/gateway/app_gateway.py:L3205–L3254](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/app_gateway.py#L3205-L3254) + + + + + +**Retry delay starts at 2.0s and doubles per failed attempt, capped at 60.0s** +delay_seconds 初始 2.0;每次 set_conf 抛异常后 expected_revision 刷新且 delay_seconds = min(delay_seconds * 2, 60.0),再 continue 进入下一轮。 + +来源:[jiuwenswarm/gateway/app_gateway.py:L3205–L3242](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/app_gateway.py#L3205-L3242) + + + + + +**Retry correctness depends on channel_manager's conf revision counter** +_retry 通过 channel_manager.get_conf_revision(channel_name) 与 expected_revision 比较来取消,并用 channel_manager.set_conf 应用/回滚配置;注释说明 set_conf 在回调出错后会回滚可见快照,因此失败时还要 set_conf(channel_name, {}) 让变化检测器也回滚。 + +来源:[jiuwenswarm/gateway/app_gateway.py:L3211–L3241](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/app_gateway.py#L3211-L3241) + + + + + +**Revision mismatch cancels the retry; set_conf failure logs, resets to empty conf, and backs off** +revision 不匹配时记 info 日志并 return(放弃重试);set_conf 抛异常时记 warning,随后尝试 set_conf(channel_name, {}),若该重置也失败仅再记 warning,刷新 expected_revision 后按指数退避继续重试。 + +来源:[jiuwenswarm/gateway/app_gateway.py:L3211–L3242](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/app_gateway.py#L3211-L3242) + + + + + +**Background retry isolates optional channels but needs a revision guard against stale snapshots** +设计推断(非作者历史意图): + +推断:后台任务让失败的可选频道不阻塞启动(docstring 明示 'without delaying Web/Cron startup'),代价是必须靠 revision 比较防止用户在 Settings 改动后被旧启动快照复活配置;guard 缺失或 revision 未递增时会错误重放旧配置。 + +来源:[jiuwenswarm/gateway/app_gateway.py:L3197–L3216](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/app_gateway.py#L3197-L3216) + + + diff --git a/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-gateway-health-check.md b/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-gateway-health-check.md new file mode 100644 index 00000000..b2750e1f --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-gateway-health-check.md @@ -0,0 +1,71 @@ +--- +title: "Gateway HealthCheck 周期探活服务:实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/health_check/health_check.py:L128-L134, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/health_check/health_check.py:L332-L351, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/health_check/health_check.py:L166-L175, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/health_check/health_check.py:L336-L340, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/gateway/test_heartbeat_contracts.py:L45-L64, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/health_check/health_check.py:L142-L150, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/health_check/health_check.py:L177-L216, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/health_check/health_check.py:L76-L92, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/health_check/health_check.py:L9-L18, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/health_check/health_check.py:L200-L207] +feature: "gateway-health-check" +entry_points: ["jiuwenswarm/gateway/health_check/__init__.py", "jiuwenswarm/gateway/health_check/health_check.py"] +source_globs: ["jiuwenswarm/gateway/health_check/__init__.py", "jiuwenswarm/gateway/health_check/health_check.py", "jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py"] +--- + +# Gateway HealthCheck 周期探活服务:实现深读 + +[功能概览](feature-gateway-health-check.md) · [owner 入口](_index.md) + + +**start 防重入后启动循环;_tick 在活跃时段构造 E2A 探活并标记成功状态** +start 在 self._running 已为真时直接返回,否则置真并用 asyncio.create_task 启动 _run_loop 并打 INFO 日志(含 interval_seconds)。每次 _tick 先经 _is_active_now() 守卫,不活跃则打 debug 日志并返回;随后用毫秒时间戳加 secrets.token_hex(3) 生成 request_id 与 session_id,经 e2a_from_agent_fields 构造以 config.channel_id 为通道的探活信封(params 含 HEALTH_CHECK_PROMPT)。若 timeout_seconds 非 None 且 > 0 则用 asyncio.wait_for 包裹 agent_client.send_request,否则直接 await;成功后置 _last_tick_at 与 _last_tick_ok = True。 + +来源:[jiuwenswarm/gateway/health_check/health_check.py:L142–L150](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/health_check/health_check.py#L142-L150), [jiuwenswarm/gateway/health_check/health_check.py:L177–L216](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/health_check/health_check.py#L177-L216) + + + + + +**构造注入 agent_client/config/可选 message_handler;update_conf 校验 every 并按参数就地更新** +__init__ 接受 agent_client、HealthCheckConfig 与可选 message_handler;update_conf 中 every 非 None 时要求 >0 否则抛 ValueError("health_check 'every' must be > 0"),target/active_hours 非 None 时写入 _config;三者全为 None 则直接返回不改状态。 + +来源:[jiuwenswarm/gateway/health_check/health_check.py:L128–L134](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/health_check/health_check.py#L128-L134), [jiuwenswarm/gateway/health_check/health_check.py:L332–L351](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/health_check/health_check.py#L332-L351) + + + + + +**HealthCheckConfig 默认值:timeout_seconds/relay_channel_id/active_hours 默认 None,channel_id 默认 HEALTH_CHECK_CHANNEL_ID** +interval_seconds 为必填 float;timeout_seconds 默认 None(文档注明可选、提供则 MUST > 0,_tick 仅在非 None 且 > 0 时套 asyncio.wait_for);channel_id 默认常量 HEALTH_CHECK_CHANNEL_ID(文档注明默认 __health_check__);relay_channel_id 默认 None,文档说明从 .env 的 HEARTBEAT_RELAY_CHANNEL_ID 读取且为 None 则不回传;active_hours 默认 None 表示始终生效。模块文档说明配置已从 config.yaml 的 heartbeat 段迁移到 health_check 段,环境变量保留 HEARTBEAT_RELAY_CHANNEL_ID 等旧名。 + +来源:[jiuwenswarm/gateway/health_check/health_check.py:L76–L92](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/health_check/health_check.py#L76-L92), [jiuwenswarm/gateway/health_check/health_check.py:L9–L18](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/health_check/health_check.py#L9-L18), [jiuwenswarm/gateway/health_check/health_check.py:L200–L207](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/health_check/health_check.py#L200-L207) + + + + + +**循环吞掉普通异常继续运行,CancelledError 退出;update_conf 对 every<=0 抛 ValueError** +_run_loop 捕获 asyncio.CancelledError 后 break 结束循环;其他 Exception 仅 logger.exception("Gateway health check loop error") 后继续下一轮。update_conf 在 every<=0 时抛 ValueError,由调用方处理。 + +来源:[jiuwenswarm/gateway/health_check/health_check.py:L166–L175](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/health_check/health_check.py#L166-L175), [jiuwenswarm/gateway/health_check/health_check.py:L336–L340](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/health_check/health_check.py#L336-L340) + + + + + +**宽捕获换取循环存活,代价是单次探活失败仅以日志呈现(推断)** +设计推断(非作者历史意图): + +收益:_run_loop 对普通异常宽捕获使周期探活不会因一次 _tick 错误退出;成本:此类失败只通过 logger.exception 呈现,循环本身不重试加速也不上报(依据 shown 实现,属推断)。 + +来源:[jiuwenswarm/gateway/health_check/health_check.py:L166–L175](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/health_check/health_check.py#L166-L175) + + + + + +**运行时测试断言旧 heartbeat.relay 在入口归一化为 HEALTH_CHECK_RELAY 并保留别名** +test_legacy_health_check_relay_normalizes_at_gateway_ingress 实际调用 MessageHandler._response_to_message 并断言 message.event_type is EventType.HEALTH_CHECK_RELAY 且 payload 同时含 health_check.relay 与 heartbeat/health_check 双键(未在本会话执行)。 + +来源:[tests/unit_tests/gateway/test_heartbeat_contracts.py:L45–L64](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/gateway/test_heartbeat_contracts.py#L45-L64) + + + diff --git a/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-gateway-server-multi-route-ws.md b/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-gateway-server-multi-route-ws.md new file mode 100644 index 00000000..3bbf0db5 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-gateway-server-multi-route-ws.md @@ -0,0 +1,62 @@ +--- +title: "GatewayServer 多路由 WebSocket 宿主与会话/请求路由表:实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L943-L977, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/gateway/test_app_gateway_acp.py:L656-L668, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L644-L663, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L785-L806, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L900-L925] +feature: "gateway-server-multi-route-ws" +entry_points: ["jiuwenswarm/gateway/app_gateway.py"] +source_globs: ["jiuwenswarm/gateway/app_gateway.py", "jiuwenswarm/gateway/channel_manager/channel_manager.py", "jiuwenswarm/gateway/routing/route_binding.py", "jiuwenswarm/gateway/channel_manager/base.py", "jiuwenswarm/gateway/routing/keys.py"] +--- + +# GatewayServer 多路由 WebSocket 宿主与会话/请求路由表:实现深读 + +[功能概览](feature-gateway-server-multi-route-ws.md) · [owner 入口](_index.md) + + +**_send_frame_to_ws 在发送前检查 ws 开合,序列化 frame 为 JSON 后经 ws.send 发送** +对带 channel_id/request_id/session_id 的 frame:_ws_is_open 要求 ws 非 None 且 closed 属性为假,否则直接返回 False;通过则 await ws.send(json.dumps(frame, ensure_ascii=False)) 并在本地返回 True。 + +来源:[jiuwenswarm/gateway/app_gateway.py:L900–L925](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/app_gateway.py#L900-L925) + + + + + +**_bind_route_session_client 返回 bool;session_bind_handler 可为同步或协程** +入参 (route: RouteConfig, session_id, ws)。session 键为 None、或存在其它未关闭 ws 时返回 False;成功写入映射返回 True。绑定成功且 existing_ws is not ws 且 route.session_bind_handler 非 None 时调用 handler(route.channel_id, session_id),若结果是协程则 await;异常被捕获并记 warning,仍返回 True。 + +来源:[jiuwenswarm/gateway/app_gateway.py:L943–L977](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/app_gateway.py#L943-L977) + + + + + +**RouteConfig 默认值:空 frozenset、空 local_handlers、ws_channel=None 不委托** +每条路由(如 /acp、/cli)的 RouteConfig 中 forward_methods 与 forward_no_local_handler_methods 默认 frozenset(),local_handlers 默认空 dict,各 handler/interceptor 与 ws_channel 默认 None;ws_channel=None 表示该路由无需把 ws 委托注册进外部 Channel。 + +来源:[jiuwenswarm/gateway/app_gateway.py:L644–L663](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/app_gateway.py#L644-L663) + + + + + +**二元组兼容旧路径 vs 可选 agent_ref 第三维** +设计推断(非作者历史意图): + +(推断)_client_route_key 保持不传 agent_ref 时返回二元组以兼容旧索引路径,收益是旧调用无需改动;代价是同一 session 下二元组键无法区分多个 agent_ref,需调用方显式传入第三维才能共存,规范化失败(ar_str 为空)时静默退回二元组。 + +来源:[jiuwenswarm/gateway/app_gateway.py:L785–L806](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/app_gateway.py#L785-L806) + + + + + +**运行时单测覆盖:绑定返回 False、断连后提升并回调 handler** +test_gateway_server_promotes_pending_session_client_after_stale_owner_cleanup 断言 _bind_route_session_client 返回 False,await _connection_handler(old_ws, "/tui") 后 disconnected == [([("tui","sess-race")], [])]、rebound == [("tui","sess-race")]、_session_to_client[("tui","sess-race")] is new_ws。未执行,仅引用现有断言。 + +来源:[tests/unit_tests/gateway/test_app_gateway_acp.py:L656–L668](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/gateway/test_app_gateway_acp.py#L656-L668) + + + diff --git a/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-im-attachment-persist-hook-969909e1.md b/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-im-attachment-persist-hook-969909e1.md new file mode 100644 index 00000000..4f37e3d4 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-im-attachment-persist-hook-969909e1.md @@ -0,0 +1,53 @@ +--- +title: "IM Attachment Persist Hook (E2A + HTTP Bridge):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/channel/test_attachment_persist.py:L39-L46, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/channel/test_attachment_persist.py:L113-L122, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/channel/test_attachment_persist.py:L40-L46, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/channel/test_attachment_persist.py:L220-L234, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/channel_manager.py:L255-L262, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/channel/test_attachment_persist.py:L93-L109, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/channel/test_attachment_persist.py:L184-L199] +feature: "im-attachment-persist-hook-969909e1" +entry_points: ["jiuwenswarm/gateway/channel_manager/channel_manager.py"] +source_globs: ["jiuwenswarm/gateway/channel_manager/channel_manager.py"] +--- + +# IM Attachment Persist Hook (E2A + HTTP Bridge):实现深读 + +[功能概览](feature-im-attachment-persist-hook-969909e1.md) · [owner 入口](_index.md) + + +**Hook contract: async (content, category, filename) returning a dict with path/name/size/mime_type** +The wired hook is awaited as hook(b"x", "images", "a.png") and returns a dict whose keys include path, name, size, mime_type; FeishuFileService exposes set_persist_hook to install it, and the service's _persist_downloaded_file uses it. + +来源:[tests/unit_tests/channel/test_attachment_persist.py:L39–L46](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/channel/test_attachment_persist.py#L39-L46), [tests/unit_tests/channel/test_attachment_persist.py:L113–L122](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/channel/test_attachment_persist.py#L113-L122) + + + + + +**Hook channel_id defaults to "im" when platform is falsy** +Within the shown hook body, channel_id is passed as `platform or "im"` with label "im.file_persist"; no other setting or precedence is visible in the offered lines. + +来源:[jiuwenswarm/gateway/channel_manager/channel_manager.py:L255–L262](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/channel_manager/channel_manager.py#L255-L262) + + + + + +**Large attachments routed to HTTP bridge instead of base64 E2A: avoids frame limit, adds failing upload step** +设计推断(非作者历史意图): + +Inference from the tests' docstrings: attachments larger than E2A_PAYLOAD_MAX_BYTES are uploaded via the authenticated HTTP bridge rather than base64-in-E2A to stay under the internal WS ~8MB frame limit (benefit), at the cost of an extra network step whose failure raises and fails the whole message as retryable (per decision D6 docstring) rather than degrading to inline delivery. + +来源:[tests/unit_tests/channel/test_attachment_persist.py:L93–L109](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/channel/test_attachment_persist.py#L93-L109), [tests/unit_tests/channel/test_attachment_persist.py:L184–L199](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/channel/test_attachment_persist.py#L184-L199) + + + + + +**Runtime tests: hook failure raises AttachmentPersistError; AgentOS hook raises RuntimeError on user_id gap** +test_persist_hook_failure_raises_attachment_persist_error installs a failing hook and asserts pytest.raises(AttachmentPersistError) around _persist_downloaded_file; test_agentos_attachment_never_falls_back_to_gateway_workspace asserts channel.hook is not None and pytest.raises(RuntimeError, match="authenticated AgentOS user_id") on hook(b"x", "images", "a.png"). Not executed here. + +来源:[tests/unit_tests/channel/test_attachment_persist.py:L40–L46](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/channel/test_attachment_persist.py#L40-L46), [tests/unit_tests/channel/test_attachment_persist.py:L220–L234](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/channel/test_attachment_persist.py#L220-L234) + + + diff --git a/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-im-channel-hot-reconfig.md b/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-im-channel-hot-reconfig.md new file mode 100644 index 00000000..fecc90be --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-im-channel-hot-reconfig.md @@ -0,0 +1,62 @@ +--- +title: "IM Channel Hot Reconfiguration (_apply_channel_config lifecycle across 11 channels):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/channel_manager.py:L362-L364, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L3191-L3196, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L3205-L3242, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L2579-L2586, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L2729-L2745, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L3210-L3212, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L3197-L3203, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L3229-L3239, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/channel_manager.py:L366-L387] +feature: "im-channel-hot-reconfig" +entry_points: ["jiuwenswarm/gateway/app_gateway.py"] +source_globs: ["jiuwenswarm/gateway/app_gateway.py", "jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py"] +--- + +# IM Channel Hot Reconfiguration (_apply_channel_config lifecycle across 11 channels):实现深读 + +[功能概览](feature-im-channel-hot-reconfig.md) · [owner 入口](_index.md) + + +**ChannelManager.get_conf_revision returns the per-channel write revision, defaulting to 0** +get_conf_revision(channel_id) returns self._conf_revisions.get(channel_id, 0), so callers reading a channel that has never had a configuration write recorded observe revision 0. The retry helper consumes this value to detect newer configuration writes. + +来源:[jiuwenswarm/gateway/channel_manager/channel_manager.py:L362–L364](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/channel_manager/channel_manager.py#L362-L364), [jiuwenswarm/gateway/app_gateway.py:L3191–L3196](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/app_gateway.py#L3191-L3196) + + + + + +**Retry delay starts at 2.0s and backs off doubling capped at 60.0s per failed attempt** +Inside _retry, delay_seconds starts at 2.0; after each failed set_conf it is updated to min(delay_seconds * 2, 60.0) and expected_revision is re-read from channel_manager.get_conf_revision before the next attempt. + +来源:[jiuwenswarm/gateway/app_gateway.py:L3205–L3242](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/app_gateway.py#L3205-L3242) + + + + + +**Reapply is coupled to ChannelManager pop/stop and adapter registries; retry is coupled to get_conf_revision** +The feishu/xiaoyi apply branches call channel_manager.pop_channels_by_id and _stop_channel, and lazily import the platform connect module only inside the non-empty-apps branch, keeping heavy platform dependencies off disabled paths. _schedule_channel_config_retry depends on channel_manager.get_conf_revision(channel_name); a differing revision makes the retry stale. + +来源:[jiuwenswarm/gateway/app_gateway.py:L2579–L2586](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/app_gateway.py#L2579-L2586), [jiuwenswarm/gateway/app_gateway.py:L2729–L2745](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/app_gateway.py#L2729-L2745), [jiuwenswarm/gateway/app_gateway.py:L3210–L3212](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/app_gateway.py#L3210-L3212) + + + + + +**ChannelManager.set_conf rolls back its config dict and re-raises when the rebuild callback throws** +set_conf increments the channel's revision and stores a merged config before awaiting the on_config_updated callback; if that callback raises, the previous config dict is restored and the exception propagates to the caller. Only the manager's config dict is restored — the shown lines state no guarantee about already-stopped integrations. + +来源:[jiuwenswarm/gateway/channel_manager/channel_manager.py:L366–L387](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/channel_manager/channel_manager.py#L366-L387) + + + + + +**Detached retry isolates optional-channel failures without blocking startup, at the cost of resurrection risk handled only by revision checks** +设计推断(非作者历史意图): + +Benefit (documented in the docstring): retrying one failed optional channel avoids delaying Web/Cron startup. Cost (inference): a stale snapshot could resurrect a config the user disabled, mitigated only by comparing get_conf_revision to expected_revision each 2–60s cycle; the reset-to-empty set_conf on error is another extra write that can itself fail and only be logged. + +来源:[jiuwenswarm/gateway/app_gateway.py:L3197–L3203](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/app_gateway.py#L3197-L3203), [jiuwenswarm/gateway/app_gateway.py:L3229–L3239](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/app_gateway.py#L3229-L3239) + + + diff --git a/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-locale-conf-rpc.md b/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-locale-conf-rpc.md new file mode 100644 index 00000000..e73cb8e8 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-locale-conf-rpc.md @@ -0,0 +1,71 @@ +--- +title: "界面语言配置 RPC(preferred_language):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L3824-L3836, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L3803-L3807, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L3795-L3807, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L3832-L3836, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L3818-L3822, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L3851-L3865] +feature: "locale-conf-rpc" +entry_points: ["jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py"] +source_globs: ["jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py"] +--- + +# 界面语言配置 RPC(preferred_language):实现深读 + +[功能概览](feature-locale-conf-rpc.md) · [owner 入口](_index.md) + + +**locale.set_conf 在无 agent 客户端或旧版共享目录客户端时的本地写回分支** +在 locale.set_conf 处理回调内,若 _resolve(agent_client) 返回 None 或是旧版共享目录客户端,则调用 update_preferred_language_in_config(lang) 写回配置,成功时以 ok=True、payload={"preferred_language": lang} 响应;若写回抛异常,记录 warning 并以 ok=False、error=str(e)、code="INTERNAL_ERROR" 响应。两条路径均随后 return,不进入代理分支;仅在非本地分支才以 params={"preferred_language": lang}、req_method=ReqMethod.LOCALE_SET_CONF 调用 proxy_unary_request 转发。 + +来源:[jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L3851–L3865](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py#L3851-L3865) + + + + + +**locale.set_conf requires a dict params object with a string preferred_language; non-dict gets BAD_REQUEST** +_locale_set_conf rejects params that are not a dict with channel.send_response(ok=False, error="params must be object", code="BAD_REQUEST") and returns; it then reads params.get("preferred_language") and guards that it is a str. _locale_get_conf/set_conf share the web-handler callback signature (ws, req_id, params, session_id, user_id=None). + +来源:[jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L3824–L3836](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py#L3824-L3836) + + + + + +**Local-branch language default is "zh" via cfg.get("preferred_language") or "zh", lowercased and stripped** +In the local/legacy branch of _locale_get_conf, a missing or falsy preferred_language in get_config() yields "zh" after strip().lower() normalization; this default applies only to that branch, not the proxied AgentServer path. + +来源:[jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L3803–L3807](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py#L3803-L3807) + + + + + +**Handlers couple to e2a_proxy (proxy_unary_request, is_legacy_shared_directory_client) and ReqMethod.LOCALE_GET_CONF** +Both locale handlers import proxy_unary_request from jiuwenswarm.gateway.routing.e2a_proxy inside the callback; get_conf also imports is_legacy_shared_directory_client to route legacy shared-directory clients to the local config read instead of the AgentServer proxy. + +来源:[jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L3795–L3807](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py#L3795-L3807), [jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L3824–L3836](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py#L3824-L3836) + + + + + +**Non-dict params to locale.set_conf return ok=False with error "params must be object" and code BAD_REQUEST** +The guard `if not isinstance(params, dict)` sends the error response and returns from the handler; no downstream proxy call or config write occurs on that branch. The shown lines do not cover the non-string preferred_language branch's response. + +来源:[jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L3832–L3836](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py#L3832-L3836) + + + + + +**get_conf dual paths: local fallback defaults to "zh", proxy path forwards to AgentServer (inferred pros and cons)** +设计推断(非作者历史意图): + +When resolved_client is None or a legacy client, _locale_get_conf reads preferred_language from local get_config() and normalizes it with `or "zh"` then strip().lower() as a fallback; on the non-local path, it is forwarded as an empty params via ReqMethod.LOCALE_GET_CONF. Inferred benefit: legacy/single-machine deployments can still obtain a language configuration with a default value; cost: the same RPC has two language value sources (local config.yaml vs AgentServer), and maintenance needs to be synchronized. + +来源:[jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L3795–L3807](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py#L3795-L3807), [jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L3818–L3822](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py#L3818-L3822) + + + diff --git a/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-thirdagent-list-switch.md b/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-thirdagent-list-switch.md new file mode 100644 index 00000000..2bd94486 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-thirdagent-list-switch.md @@ -0,0 +1,80 @@ +--- +title: "3rdagent.list / 3rdagent.switch 第三方智能体切换:实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/extensions/test_agentos_router.py:L839-L857, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/extensions/test_agentos_router.py:L1065-L1083, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/common/client/third_agent.py:L14-L49, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/agentos/agentos_router/router_client.py:L1572-L1582, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/routing/third_agent.py:L1-L17, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/extensions/test_agentos_router.py:L1407-L1420, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/common/client/third_agent.py:L55-L82, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/common/client/third_agent.py:L52-L89, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/routing/third_agent.py:L11-L17, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/common/client/third_agent.py:L17-L22, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/common/client/third_agent.py:L24-L37, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/common/client/third_agent.py:L39-L49] +feature: "thirdagent-list-switch" +entry_points: ["jiuwenswarm/extensions/agentos/agentos_router/router_client.py"] +source_globs: ["jiuwenswarm/extensions/agentos/agentos_router/router_client.py", "jiuwenswarm/common/client/third_agent.py", "jiuwenswarm/gateway/routing/third_agent.py"] +--- + +# 3rdagent.list / 3rdagent.switch 第三方智能体切换:实现深读 + +[功能概览](feature-thirdagent-list-switch.md) · [owner 入口](_index.md) + + +**thirdagent_switch on a registry agent creates one sandbox; on builtin jiuwenswarm it creates none** +In the router-client test path, thirdagent_switch(user_id="u1", agent_type="opencode", session_id="sess-1") returns ok with payload.agent_type="opencode" and payload.sandbox_id="sbx-1" after exactly one yuanrong.create; switching to agent_type="jiuwenswarm" returns ok with sandbox_id="" and zero creates. + +来源:[tests/unit_tests/extensions/test_agentos_router.py:L839–L857](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/extensions/test_agentos_router.py#L839-L857), [tests/unit_tests/extensions/test_agentos_router.py:L1065–L1083](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/extensions/test_agentos_router.py#L1065-L1083) + + + + + +**ThirdAgent abstract contract: thirdagent_list and thirdagent_switch keyword-only methods returning dicts** +ThirdAgent (ABC) declares abstract async thirdagent_list(*, user_id, current_agent_type="", access_mode="") and thirdagent_switch(*, user_id, agent_type, session_id="", params=None), both returning dict[str, Any]; access_mode selects which registry access_mode[].cmd is returned. normalize_agent_type maps empty or case-insensitive "jiuwenswarm" to "jiuwenswarm", otherwise preserves the raw string's case. + +来源:[jiuwenswarm/common/client/third_agent.py:L14–L49](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/common/client/third_agent.py#L14-L49) + + + + + +**normalize_agent_type default: empty or falsey input becomes "jiuwenswarm"; other stripped names keep case** +In ThirdAgent.normalize_agent_type, agent_type = str(raw or "").strip(), so raw that is None, empty, or any falsey value (e.g. 0, False, "") substitutes "" and yields builtin "jiuwenswarm"; only inputs whose str().strip().lower() equals "jiuwenswarm" are lowercased to the builtin, all other stripped names are returned with original case. The abstract thirdagent_list/thirdagent_switch declare keyword-only defaults current_agent_type="", access_mode="" and session_id="", params=None; access_mode selects which registry access_mode[].cmd is returned (TUI passes "tui"). + +来源:[jiuwenswarm/common/client/third_agent.py:L17–L22](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/common/client/third_agent.py#L17-L22), [jiuwenswarm/common/client/third_agent.py:L24–L37](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/common/client/third_agent.py#L24-L37), [jiuwenswarm/common/client/third_agent.py:L39–L49](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/common/client/third_agent.py#L39-L49) + + + + + +**3rdagent calls bypass E2A send_request; contract lives in common.client.third_agent re-exported by gateway** +AgentOSRouterClient.send_request states 3rdagent.list/switch are handled by the Gateway ThirdAgent (TUI local_handler), not via E2A send_request; the jiuwenswarm.gateway.routing.third_agent module only re-exports ThirdAgent, UnsupportedThirdAgent and get_unsupported_third_agent from jiuwenswarm.common.client.third_agent to keep the old import path working. + +来源:[jiuwenswarm/extensions/agentos/agentos_router/router_client.py:L1572–L1582](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/agentos/agentos_router/router_client.py#L1572-L1582), [jiuwenswarm/gateway/routing/third_agent.py:L1–L17](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/routing/third_agent.py#L1-L17) + + + + + +**未注册扩展时 UnsupportedThirdAgent 各自返回 ok=False、code="UNSUPPORTED",不抛异常** +thirdagent_list 丢弃 user_id/current_agent_type/access_mode,返回 {"ok": False, "error": "3rdagent.list requires an AgentOS Router extension", "code": "UNSUPPORTED"};thirdagent_switch 丢弃 user_id/agent_type/session_id/params,返回 error 为 "3rdagent.switch requires an AgentOS Router extension"、同样的 code。两个分支在本地返回,不 raise。 + +来源:[jiuwenswarm/common/client/third_agent.py:L55–L82](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/common/client/third_agent.py#L55-L82) + + + + + +**模块级单例默认实现换来确定性的 UNSUPPORTED 拒绝,代价是空输入下不提供任何降级列表** +设计推断(非作者历史意图): + +get_unsupported_third_agent 返回模块级 _UNSUPPORTED_THIRD_AGENT 单例;对本仓内通过 jiuwenswarm.gateway.routing.third_agent re-export 导入的调用方,无扩展时可得到确定性的 ok=False 响应(推断为收益);代价是即使 list 请求也一律失败、不返回部分目录(推断)。仅限所示实现,不跨仓保证。 + +来源:[jiuwenswarm/common/client/third_agent.py:L52–L89](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/common/client/third_agent.py#L52-L89), [jiuwenswarm/gateway/routing/third_agent.py:L11–L17](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/routing/third_agent.py#L11-L17) + + + + + +**test_unsupported_third_agent_returns_unsupported awaits both stub methods and asserts the UNSUPPORTED dicts** +The pytest asyncio test imports get_unsupported_third_agent via jiuwenswarm.gateway.routing.third_agent, calls thirdagent_list(user_id="u1", current_agent_type="jiuwenswarm") and thirdagent_switch(user_id="u1", agent_type="opencode", session_id="s1"), asserting listed["ok"] is False, code "UNSUPPORTED", and the same for switched. Evidence of assertions in the test source; not executed here. + +来源:[tests/unit_tests/extensions/test_agentos_router.py:L1407–L1420](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/extensions/test_agentos_router.py#L1407-L1420) + + + diff --git a/knowledge/repos/jiuwenswarm/components/ide-clients/feature-depth-ide-file-edit-diff-apply.md b/knowledge/repos/jiuwenswarm/components/ide-clients/feature-depth-ide-file-edit-diff-apply.md new file mode 100644 index 00000000..d4ee7715 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/ide-clients/feature-depth-ide-file-edit-diff-apply.md @@ -0,0 +1,51 @@ +--- +title: "IDE 端代理文件编辑直接应用(DiffApplier):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L81-L83, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/editor/DiffApplier.kt:L70-L78, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L112-L119, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/editor/DiffApplier.kt:L309-L310, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L70-L85, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L112-L123, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L273-L286, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L75-L79] +feature: "ide-file-edit-diff-apply" +entry_points: ["jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/ui/ChatToolWindow.kt", "jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts"] +source_globs: ["jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/ui/ChatToolWindow.kt", "jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts", "jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/editor/DiffApplier.kt", "jiuwenswarm/channels/ide/packages/vscode-extension/src/ui/ChatPanel.ts"] +--- + +# IDE 端代理文件编辑直接应用(DiffApplier):实现深读 + +[功能概览](feature-ide-file-edit-diff-apply.md) · [owner 入口](_index.md) + + +**handleToolCall 按 EDIT_TOOLS 与参数守卫分派 write_file 到 writeEntireFile** +回调先取 payload.tool_name,不在 EDIT_TOOLS 集合即返回 false;parseArguments 成功后从配置读 requireApproval。write_file/create_file 分支在 args.path 缺失时返回 false,否则以 isNew = create_file 或文件不存在 调 writeEntireFile 并返回其布尔结果。 + +来源:[jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L70–L85](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts#L70-L85), [jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L112–L123](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts#L112-L123), [jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L273–L286](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts#L273-L286) + + + + + +**VS Code 端审批开关 jiuwenswarm.approveEdits,默认 false** +每次调用通过 vscode.workspace.getConfiguration('jiuwenswarm').get('approveEdits', false) 读取,默认不要求审批,布尔值传入 applyStrReplace/writeEntireFile。JetBrains 端对应 settings.approveEdits 与 autoApplyEdits 两个设置。 + +来源:[jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L81–L83](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts#L81-L83), [jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/editor/DiffApplier.kt:L70–L78](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/editor/DiffApplier.kt#L70-L78) + + + + + +**依赖 vscode 配置 API、fs 存在性检查与 EDIT_TOOLS 工具名集合** +VS Code 分支依赖 vscode.workspace.getConfiguration 与 fs.existsSync 判定 isNew;JetBrains 端依赖 JiuwenSwarmSettings.instance() 提供设置,EDIT_TOOLS 集合限定四种工具名(str_replace_editor、write_file、create_file、edit_file)。 + +来源:[jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L112–L119](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts#L112-L119), [jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/editor/DiffApplier.kt:L309–L310](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/editor/DiffApplier.kt#L309-L310) + + + + + +**参数不可解析时 console.warn 并返回 false;path 缺失静默返回 false** +parseArguments 对非对象且非字符串的 arguments 或 JSON.parse 抛错返回 null;handleToolCall 据此记录 console.warn 后返回 false,不进入写分支。write_file 分支中 filePath 为空时直接 return false,无告警。 + +来源:[jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L75–L79](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts#L75-L79), [jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L273–L286](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts#L273-L286), [jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L112–L119](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts#L112-L119) + + + diff --git a/knowledge/repos/jiuwenswarm/components/ide-clients/feature-depth-ide-turn-rewind-snapshot.md b/knowledge/repos/jiuwenswarm/components/ide-clients/feature-depth-ide-turn-rewind-snapshot.md new file mode 100644 index 00000000..67355b0e --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/ide-clients/feature-depth-ide-turn-rewind-snapshot.md @@ -0,0 +1,62 @@ +--- +title: "IDE 单轮文件快照与回退(Rewind):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L32-L48, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L53-L64, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/settings/JiuwenSwarmSettings.kt:L36-L39, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/settings/JiuwenSwarmSettings.kt:L123-L125, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L55-L63, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L249-L255, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/ui/ChatPanel.ts:L929-L940, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L245-L257, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/ui/ChatPanel.ts:L929-L934, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L22-L24, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L41-L53] +feature: "ide-turn-rewind-snapshot" +entry_points: ["jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/ui/ChatToolWindow.kt", "jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts"] +source_globs: ["jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/ui/ChatToolWindow.kt", "jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts", "jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/settings/JiuwenSwarmSettings.kt"] +--- + +# IDE 单轮文件快照与回退(Rewind):实现深读 + +[功能概览](feature-ide-turn-rewind-snapshot.md) · [owner 入口](_index.md) + + +**handleRewind:空快照直接返回,否则恢复、清空并回报 rewind_done** +handleRewind 先取 lastTurnSnapshots 的副本,若 size === 0 直接 return;否则 await performRewind,随后 clearLastTurnSnapshots,并按 failed 是否为 0 组装消息 postToWebview({type:'rewind_done', restored, failed})。performRewind 内对每个条目:originalContent === null 且文件存在时 fs.unlinkSync 删除;非 null 时走恢复原内容分支(该写回语句体未在展示范围内)。 + +来源:[jiuwenswarm/channels/ide/packages/vscode-extension/src/ui/ChatPanel.ts:L929–L940](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/vscode-extension/src/ui/ChatPanel.ts#L929-L940), [jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L245–L257](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts#L245-L257) + + + + + +**模块导出三个快照生命周期函数,promoteSnapshots 返回是否存在可回退文件** +promoteSnapshots(): boolean 在 currentTurnSnapshots.size === 0 时返回 false,否则提升并返回 true;getLastTurnSnapshots(): Map 返回拷贝;clearLastTurnSnapshots(): void 清空 lastTurnSnapshots;ensureSnapshot(filePath) 无返回值。 + +来源:[jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L32–L48](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts#L32-L48), [jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L53–L64](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts#L53-L64) + + + + + +**JetBrains 设置 rewindEnabled 默认 true,注释声明其用于快照/回退** +JiuwenSwarmSettings.State 中 rewindEnabled: Boolean = true,注释为 "When true, snapshot files before agent edits so the rewind feature can become restore them." 的意图性说明(原文:snapshot files before agent edits so the rewind feature can restore them)。所示片段没有消费该开关的代码,因此其 gating 效果在本证据内未确立。 + +来源:[jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/settings/JiuwenSwarmSettings.kt:L36–L39](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/settings/JiuwenSwarmSettings.kt#L36-L39), [jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/settings/JiuwenSwarmSettings.kt:L123–L125](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/settings/JiuwenSwarmSettings.kt#L123-L125) + + + + + +**ChatPanel 的回退依赖 DiffApplier 的三个导出与模块级 Map 状态** +handleRewind 调用 DiffApplier.getLastTurnSnapshots()(返回新 Map 副本)、performRewind(snapshots) 和 clearLastTurnSnapshots()。快照状态是 DiffApplier.ts 模块级变量 currentTurnSnapshots / lastTurnSnapshots;ensureSnapshot 用同步 fs.existsSync/readFileSync 写入,ChatPanel 不自持快照。 + +来源:[jiuwenswarm/channels/ide/packages/vscode-extension/src/ui/ChatPanel.ts:L929–L934](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/vscode-extension/src/ui/ChatPanel.ts#L929-L934), [jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L22–L24](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts#L22-L24), [jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L41–L53](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts#L41-L53) + + + + + +**读取失败时快照记为 null,回退会把现存文件当作本轮新建而删除** +设计推断(非作者历史意图): + +ensureSnapshot 的 catch 分支将 currentTurnSnapshots.set(filePath, null);performRewind 对 null 快照在 fs.existsSync 为真时执行 unlinkSync。即读取异常与"编辑前不存在"不可区分,回退会删除该文件。 + +来源:[jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L55–L63](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts#L55-L63), [jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L249–L255](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts#L249-L255) + + + diff --git a/knowledge/repos/jiuwenswarm/components/ide-vscode/feature-depth-ide-terminal-command-mirror.md b/knowledge/repos/jiuwenswarm/components/ide-vscode/feature-depth-ide-terminal-command-mirror.md new file mode 100644 index 00000000..37f6be9e --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/ide-vscode/feature-depth-ide-terminal-command-mirror.md @@ -0,0 +1,71 @@ +--- +title: "IDE 终端命令镜像执行:实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/terminal/TerminalManager.kt:L40-L47, "openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:docs/zh/ide/jetbrains/JetBrains插件.md:L13-L24", openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/terminal/TerminalManager.ts:L9-L18, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/terminal/TerminalManager.kt:L23-L38, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/terminal/TerminalManager.kt:L23-L65, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/terminal/TerminalManager.ts:L20-L48, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/terminal/TerminalManager.ts:L3-L18, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/terminal/TerminalManager.ts:L34-L65, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/terminal/TerminalManager.kt:L10-L38] +feature: "ide-terminal-command-mirror" +entry_points: ["jiuwenswarm/channels/ide/packages/vscode-extension/src/terminal/TerminalManager.ts", "jiuwenswarm/channels/ide/packages/vscode-extension/src/ui/ChatPanel.ts"] +source_globs: ["jiuwenswarm/channels/ide/packages/vscode-extension/src/terminal/TerminalManager.ts", "jiuwenswarm/channels/ide/packages/vscode-extension/src/ui/ChatPanel.ts", "jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/terminal/TerminalManager.kt"] +--- + +# IDE 终端命令镜像执行:实现深读 + +[功能概览](feature-ide-terminal-command-mirror.md) · [owner 入口](_index.md) + + +**VS Code runCommand:模块级 activeTerminal 惰性建、复用并 show() 后 sendText** +runCommand 在模块级 activeTerminal 为空时创建名为 'JiuwenSwarm' 的终端,cwd 取传入值,否则回退第一个工作区文件夹(无工作区时为 undefined);随后 activeTerminal.show() 并 sendText(command),命令文本不在此分支解析或校验。 + +来源:[jiuwenswarm/channels/ide/packages/vscode-extension/src/terminal/TerminalManager.ts:L3–L18](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/vscode-extension/src/terminal/TerminalManager.ts#L3-L18) + + + + + +**extractCommand/extractArguments:多形态 payload 解析,返回首个命中键的 trim 后字符串或 undefined** +extractCommand 取 extractArguments 结果、payload.arguments 或 payload 本身作为 args(非对象则返回 undefined),再取 command/cmd/shell_cmd/bash_command 中首个真值并 String(...).trim()。extractArguments 优先 tool_call.arguments,tool_call 为对象但无对象型 arguments 时返回 tool_call 本身(此时不再查 tool_input/input),否则依次取 tool_input、input。 + +来源:[jiuwenswarm/channels/ide/packages/vscode-extension/src/terminal/TerminalManager.ts:L34–L65](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/vscode-extension/src/terminal/TerminalManager.ts#L34-L65) + + + + + +**JetBrains runCommand 受设置 runCommandsInTerminal 守卫,文档默认为开** +Kotlin runCommand 在执行前检查 JiuwenSwarmSettings.instance().runCommandsInTerminal,为假即 return。JetBrains 设置文档列出「在 IDE 终端中运行命令」默认值为「开」。所示 VS Code runCommand 片段不读取任何配置项。 + +来源:[jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/terminal/TerminalManager.kt:L40–L47](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/terminal/TerminalManager.kt#L40-L47), [docs/zh/ide/jetbrains/JetBrains插件.md:L13–L24](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/docs/zh/ide/jetbrains/JetBrains%E6%8F%92%E4%BB%B6.md#L13-L24), [jiuwenswarm/channels/ide/packages/vscode-extension/src/terminal/TerminalManager.ts:L9–L18](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/vscode-extension/src/terminal/TerminalManager.ts#L9-L18) + + + + + +**Kotlin 侧经反射耦合 TerminalView/ShellTerminalWidget;VS Code 侧依赖 vscode.window 终端 API** +Kotlin init 通过 Class.forName 解析 org.jetbrains.plugins.terminal.TerminalView 与 ShellTerminalWidget 的方法,编译期不依赖 Terminal 插件;VS Code 直接调用 vscode.window.createTerminal/show/sendText。Kotlin 还依赖 ToolWindowManager 取 "Terminal" 工具窗。 + +来源:[jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/terminal/TerminalManager.kt:L23–L38](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/terminal/TerminalManager.kt#L23-L38), [jiuwenswarm/channels/ide/packages/vscode-extension/src/terminal/TerminalManager.ts:L9–L18](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/vscode-extension/src/terminal/TerminalManager.ts#L9-L18) + + + + + +**Kotlin 反射缺失或执行异常被捕获并降级为日志;VS Code dispose 吞掉异常** +Kotlin init 反射失败时记 LOG.info 并让 Method 保持 null,runCommand 随后因 tv/gi 等为 null 提前 return(终端集成禁用);runCommand 体内异常被 catch 记 LOG.warn。VS Code disposeTerminal 用 try/catch 忽略 dispose 异常并将 activeTerminal 置 undefined。extractCommand 在无命令键时返回 undefined,由调用方决定后续。 + +来源:[jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/terminal/TerminalManager.kt:L23–L65](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/terminal/TerminalManager.kt#L23-L65), [jiuwenswarm/channels/ide/packages/vscode-extension/src/terminal/TerminalManager.ts:L20–L48](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/vscode-extension/src/terminal/TerminalManager.ts#L20-L48) + + + + + +**JetBrains 端反射调用 Terminal API:编译期解耦,代价是初始化失败即静默禁用** +设计推断(非作者历史意图): + +TerminalManager 在 init 中通过 Class.forName/getMethod 反射获取 TerminalView 与 ShellTerminalWidget 的方法句柄,任何 Exception 仅 LOG.info 后继续,runCommand 中任一句柄为 null 即直接 return。推断(非作者意图):这使插件可在缺少 Terminal 插件时编译,但运行时集成失败只留下日志,命令镜像被静默跳过。 + +来源:[jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/terminal/TerminalManager.kt:L10–L38](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/terminal/TerminalManager.kt#L10-L38), [jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/terminal/TerminalManager.kt:L40–L47](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/terminal/TerminalManager.kt#L40-L47) + + + diff --git a/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-chat-session-stats-dashboard.md b/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-chat-session-stats-dashboard.md new file mode 100644 index 00000000..02ae3982 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-chat-session-stats-dashboard.md @@ -0,0 +1,60 @@ +--- +title: "Chat Session Stats Bar and Per-Turn Mini Charts:实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/shared-webview/chat.html:L3398-L3407, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/shared-webview/chat.html:L3391-L3396, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/shared-webview/chat.html:L4348-L4361, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/shared-webview/chat.html:L4352-L4364] +feature: "chat-session-stats-dashboard" +entry_points: ["jiuwenswarm/channels/ide/packages/shared-webview/chat.html"] +source_globs: ["jiuwenswarm/channels/ide/packages/shared-webview/chat.html"] +--- + +# Chat Session Stats Bar and Per-Turn Mini Charts:实现深读 + +[功能概览](feature-chat-session-stats-dashboard.md) · [owner 入口](_index.md) + + +**renderTokenCounter callback: only when state.contextWindow > 0, derives pct and estimated used tokens** +调用 renderTokenCounter(total) 时先记录 state.lastTokenTotal;若 #token-counter 元素不存在直接返回;仅当 state.contextWindow > 0 时计算 pct=contextUsagePct(),若 ctxUsed<=0 且 pct!=null 则用 Math.round(state.contextWindow*pct/100) 估算已用 tokens。 + +来源:[jiuwenswarm/channels/ide/packages/shared-webview/chat.html:L3398–L3407](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/shared-webview/chat.html#L3398-L3407) + + + + + +**updateTokenBar: no-argument DOM updater reading token/state fields, early-return when bar elements absent** +updateTokenBar() takes no arguments and reads total = state.hostMetrics.sessionTokens || state.sessionStats.totalTokens, plus state.contextWindow, state.contextUsagePercent and state.contextTokensUsed; it requires elements with ids 'token-bar-wrap' and 'token-bar-fill' and returns without side effects if either is missing (line 4361). + +来源:[jiuwenswarm/channels/ide/packages/shared-webview/chat.html:L4348–L4361](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/shared-webview/chat.html#L4348-L4361) + + + + + +**Usage percent precedence: state.contextUsagePercent (non-null) wins over contextTokensUsed/contextWindow ratio** +若 state.contextUsagePercent != null 则直接使用该百分比;否则当 state.contextTokensUsed > 0 且 limit(=state.contextWindow) > 0 时计算比值;两者都不满足返回 null。未展示这些 state 字段的默认值或赋值来源。 + +来源:[jiuwenswarm/channels/ide/packages/shared-webview/chat.html:L3391–L3396](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/shared-webview/chat.html#L3391-L3396) + + + + + +**Stats display depends on state.contextWindow/contextTokensUsed and a token-counter DOM element** +renderTokenCounter 依赖全局 state 的 contextWindow、contextTokensUsed、contextUsagePercent 以及 id 为 token-counter 的 DOM 元素;元素缺失时静默返回(3400–3401 行),因此宿主未渲染该元素则整段显示不生效。 + +来源:[jiuwenswarm/channels/ide/packages/shared-webview/chat.html:L3398–L3407](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/shared-webview/chat.html#L3398-L3407) + + + + + +**updateTokenBar: null pct branch sets width 0% and removes 'visible'; missing DOM nodes cause plain early return** +When state.contextUsagePercent is null and not (state.contextTokensUsed > 0 and state.contextWindow > 0), pct becomes null and the shown branch sets fill.style.width = '0%' and removes the 'visible' class from the wrap; separately, if either DOM element is absent the function returns before any style change. + +来源:[jiuwenswarm/channels/ide/packages/shared-webview/chat.html:L4352–L4364](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/shared-webview/chat.html#L4352-L4364) + + + diff --git a/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-code-mode-branch-selector.md b/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-code-mode-branch-selector.md new file mode 100644 index 00000000..82492d01 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-code-mode-branch-selector.md @@ -0,0 +1,62 @@ +--- +title: "代码模式分支选择器(初始化/切换/创建分支):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeBranchSelector.tsx:L36-L36, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeBranchSelector.tsx:L195-L204, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeEnvironmentPanel.tsx:L4-L6, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeEnvironmentPanel.tsx:L47-L49, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeBranchSelector.tsx:L48-L48, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeBranchSelector.tsx:L80-L82, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeBranchSelector.tsx:L192-L207, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeBranchSelector.tsx:L36-L37, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeBranchSelector.tsx:L84-L97] +feature: "code-mode-branch-selector" +entry_points: ["jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeBranchSelector.tsx"] +source_globs: ["jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeBranchSelector.tsx", "jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeEnvironmentPanel.tsx"] +--- + +# 代码模式分支选择器(初始化/切换/创建分支):实现深读 + +[功能概览](feature-code-mode-branch-selector.md) · [owner 入口](_index.md) + + +**挂载时加载状态;仅在 project 存在、work_mode='code' 且非默认项目时渲染** +组件挂载后 useEffect 调用 loadStatus()(依赖 [loadStatus]);若 !project、project.work_mode !== 'code' 或 project.is_default 则整个组件返回 null。当目录不是 Git 仓库时渲染 data-variant='init' 的“初始化 Git”按钮,点击触发 initializeGit(),disabled 条件为 disabled || operating。 + +来源:[jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeBranchSelector.tsx:L80–L82](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeBranchSelector.tsx#L80-L82), [jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeBranchSelector.tsx:L192–L207](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeBranchSelector.tsx#L192-L207) + + + + + +**props 契约:compact/disabled/variant/liveRepo 均有默认值** +签名 { project, compact = false, disabled = false, variant = 'default', liveRepo = null }。调用方 CodeEnvironmentPanel 传入 compact、variant="environment"、disabled={isProcessing}、liveRepo={diffWatch.summary?.repo ?? null},即处理期间禁用、用 diffWatch 的仓库摘要实时同步分支状态。 + +来源:[jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeBranchSelector.tsx:L36–L37](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeBranchSelector.tsx#L36-L37), [jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeEnvironmentPanel.tsx:L47–L49](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeEnvironmentPanel.tsx#L47-L49) + + + + + +**默认 compact=false、disabled=false、variant='default'、liveRepo=null** +四个可选 prop 均有默认值;compact 追加 code-branch--compact 类,variant==='environment' 追加 code-branch--environment 类;disabled 与内部 operating 共同禁用初始化按钮。 + +来源:[jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeBranchSelector.tsx:L36–L36](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeBranchSelector.tsx#L36-L36), [jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeBranchSelector.tsx:L195–L204](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeBranchSelector.tsx#L195-L204) + + + + + +**被 CodeEnvironmentPanel 组合:liveRepo 来自 diffWatch,uses useWorkspaceStore 的 loadProjects** +CodeEnvironmentPanel 从 './CodeBranchSelector' 导入并在分支行渲染它,liveRepo 取自 diffWatch.summary?.repo,disabled 取 isProcessing,因此选择器的实时仓库状态与 diff 监听耦合;组件自身还从 useWorkspaceStore 取 loadProjects。 + +来源:[jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeEnvironmentPanel.tsx:L4–L6](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeEnvironmentPanel.tsx#L4-L6), [jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeEnvironmentPanel.tsx:L47–L49](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeEnvironmentPanel.tsx#L47-L49), [jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeBranchSelector.tsx:L48–L48](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeBranchSelector.tsx#L48-L48) + + + + + +**liveRepo 同步避免重新请求,但仅在已有 status 时合并** +设计推断(非作者历史意图): + +当 liveRepo 存在且 project.work_mode === 'code' 且非默认项目时,用 liveRepo 的 is_git/repo_root/branch/head/transient 覆盖本地 status.repo。收益:父面板的 diffWatch 摘要可直接驱动分支显示,无需再次 loadStatus;代价(推理):若 previous 为 null(状态尚未加载成功),该 effect 不填充 status,初始状态仍依赖 loadStatus 的结果。 + +来源:[jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeBranchSelector.tsx:L84–L97](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeBranchSelector.tsx#L84-L97) + + + diff --git a/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-code-mode-commit-push.md b/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-code-mode-commit-push.md new file mode 100644 index 00000000..74b8c2bf --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-code-mode-commit-push.md @@ -0,0 +1,60 @@ +--- +title: "提交/推送对话框(commit、push、commit_push):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeCommitPushControl.tsx:L95-L108, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/gitPublishState.ts:L5-L13, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeCommitPushControl.tsx:L117-L119, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeCommitPushControl.tsx:L133-L151, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeCommitPushControl.tsx:L10-L18, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeCommitPushControl.tsx:L1-L8, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeCommitPushControl.tsx:L133-L148, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeCommitPushControl.tsx:L139-L150, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/gitPublishState.ts:L29-L34] +feature: "code-mode-commit-push" +entry_points: ["jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeCommitPushControl.tsx"] +source_globs: ["jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeCommitPushControl.tsx"] +--- + +# 提交/推送对话框(commit、push、commit_push):实现深读 + +[功能概览](feature-code-mode-commit-push.md) · [owner 入口](_index.md) + + +**打开对话框后按 Escape 关闭(非提交中且非建分支中)** +对话框 open 时注册 document keydown 回调:按 Escape 且不在 submitting/creatingBranch 时,若分支创建区已展开则先收起并清空 branchDraft,否则 setOpen(false) 关闭整个对话框。 + +来源:[jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeCommitPushControl.tsx:L95–L108](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeCommitPushControl.tsx#L95-L108) + + + + + +**createBranch 回调契约:成功后调用 onSuccess(),仅抑制其异步拒绝** +createBranch 守卫为 status、非空 trim 后分支名且未在 creatingBranch/submitting;成功路径调用 gitClient.createBranch(project.project_id, nextBranch),随后同步调用 onSuccess(),其返回 promise 的拒绝被 .catch(() => undefined) 抑制;同步抛出的异常落入外层 catch 设为 error。 + +来源:[jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeCommitPushControl.tsx:L133–L151](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeCommitPushControl.tsx#L133-L151), [jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeCommitPushControl.tsx:L10–L18](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeCommitPushControl.tsx#L10-L18) + + + + + +**默认提交信息按 filesChanged 生成,远程名缺省回退 'origin'** +message 为空白时用 defaultCommitMessage(filesChanged):≤0 为 'Update project files',1 为 'Update 1 file',否则 'Update N files';remoteNames 在无远程分支名时返回 ['origin']。 + +来源:[jiuwenswarm/channels/web/frontend/src/features/code-mode/gitPublishState.ts:L5–L13](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/features/code-mode/gitPublishState.ts#L5-L13), [jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeCommitPushControl.tsx:L117–L119](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeCommitPushControl.tsx#L117-L119) + + + + + +**组件依赖 gitClient 与 gitPublishState 的具名导出** +组件从 './gitClient' 导入 gitClient,从 './gitPublishState' 导入 defaultCommitMessage、gitPublishErrorMessage、remoteNames 与类型 GitPublishOperation;createBranch 回调内部 await gitClient.createBranch(project.project_id, nextBranch)。 + +来源:[jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeCommitPushControl.tsx:L1–L8](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeCommitPushControl.tsx#L1-L8), [jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeCommitPushControl.tsx:L133–L148](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeCommitPushControl.tsx#L133-L148) + + + + + +**createBranch 被拒时:错误经 gitPublishErrorMessage 归一,分支面板保持打开** +若 gitClient.createBranch 抛出 nextError,catch 分支用 gitPublishErrorMessage(nextError, '创建分支失败,请重试。') 写入 error;因 setBranchCreateOpen(false) 仅在 await 成功后执行,新建分支面板保持打开,finally 将 creatingBranch 复位为 false。 + +来源:[jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeCommitPushControl.tsx:L139–L150](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeCommitPushControl.tsx#L139-L150), [jiuwenswarm/channels/web/frontend/src/features/code-mode/gitPublishState.ts:L29–L34](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/features/code-mode/gitPublishState.ts#L29-L34) + + + diff --git a/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-context-usage-indicator.md b/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-context-usage-indicator.md new file mode 100644 index 00000000..77c80b31 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-context-usage-indicator.md @@ -0,0 +1,51 @@ +--- +title: "上下文占用指示器(环形/悬浮提示/明细弹层):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx:L62-L78, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx:L142-L158, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx:L64-L78, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx:L142-L148, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/server/runtime/agent_adapter/interface_deep.py:L18674-L18701, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx:L233-L238, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/server/runtime/agent_adapter/interface.py:L5084-L5096] +feature: "context-usage-indicator" +entry_points: ["jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.css", "jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx"] +source_globs: ["jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.css", "jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx", "jiuwenswarm/server/runtime/agent_adapter/interface_deep.py", "jiuwenswarm/server/utils/stream_utils.py"] +--- + +# 上下文占用指示器(环形/悬浮提示/明细弹层):实现深读 + +[功能概览](feature-context-usage-indicator.md) · [owner 入口](_index.md) + + +**渲染前按 mode/会话/快照守卫,null 字段降级为“未上报”** +组件从 useSessionStore 按 activeSessionId 读取 mode 与 contextUsageSnapshot;当 mode 不是 'agent' 或 'team'、无 activeSessionId 或无 snapshot 时直接 return null(L142)。否则解构 snapshot.context_window,occupancy_rate/input_tokens/limit_tokens 为 null 时显示 t('chat.contextUsage.notReported'),ringPercent 仅在 rate 非 null 时计算(L144–L151)。 + +来源:[jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx:L62–L78](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx#L62-L78), [jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx:L142–L158](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx#L142-L158) + + + + + +**get_context_usage(session_id) 异步返回上下文占用统计字典** +JiuWenSwarm.get_context_usage 是 async 方法,入参 session_id(会话ID),返回包含上下文窗口总量与当前占用量、系统提示词/对话消息/工具定义各自 token 消耗及占用百分比的字典;具体统计字段由实现填充,所示行仅为文档字符串。 + +来源:[jiuwenswarm/server/runtime/agent_adapter/interface.py:L5084–L5096](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/server/runtime/agent_adapter/interface.py#L5084-L5096) + + + + + +**mode 缺省回退 'agent',snapshot 缺省 null(runtimes 查找按会话)** +组件用 `state.runtimes[activeSessionId ?? '']?.mode ?? 'agent'` 读取模式,无会话运行时时按 'agent' 处理;`contextUsageSnapshot ?? null` 缺省为 null,而 null snapshot 使组件整体不渲染(L65–L66 与 L142 守卫)。 + +来源:[jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx:L64–L78](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx#L64-L78), [jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx:L142–L148](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx#L142-L148) + + + + + +**快照构建抛异常时记 warning 并返回 None,不影响 /compact** +get_context_usage_event 的 try 块包裹 build_snapshot,except Exception 时 logger.warning("manual context usage snapshot failed", exc_info=True) 并返回 None,注释明确 usage telemetry 不得使 /compact 失败;build_snapshot 不可调用时同样返回 None(debug 日志)。前端悬浮层对 displayCacheRate 为 null 时跳过缓存命中率行。 + +来源:[jiuwenswarm/server/runtime/agent_adapter/interface_deep.py:L18674–L18701](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/server/runtime/agent_adapter/interface_deep.py#L18674-L18701), [jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx:L233–L238](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx#L233-L238) + + + diff --git a/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-frontend-incremental-lint-gate.md b/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-frontend-incremental-lint-gate.md new file mode 100644 index 00000000..b44dbc01 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-frontend-incremental-lint-gate.md @@ -0,0 +1,62 @@ +--- +title: "增量 ESLint 门禁(相对基线只报新增诊断):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs:L1-L5, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs:L16-L22, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs:L28-L31, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs:L33-L46, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs:L7-L8, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs:L26-L26, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs:L54-L61, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs:L9-L10, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs:L22-L22, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs:L28-L48, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs:L49-L72] +feature: "frontend-incremental-lint-gate" +entry_points: ["jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs"] +source_globs: ["jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs"] +--- + +# 增量 ESLint 门禁(相对基线只报新增诊断):实现深读 + +[功能概览](feature-frontend-incremental-lint-gate.md) · [owner 入口](_index.md) + + +**变更 TS/TSX 文件逐个做基线/当前 lintText 对比,按 multiset 扣除既有诊断** +对每个变更的 .ts/.tsx 文件(须位于 cwd 下且未被 ESLint ignore),用 git show 取基线内容,分别 lintText 基线与当前文本;当前诊断按 [ruleId, severity, message] 键与基线计数逐条抵扣,剩余的新诊断重算 error/warning 计数后收集到 introduced。 + +来源:[jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs:L26–L26](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs#L26-L26), [jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs:L28–L48](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs#L28-L48), [jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs:L49–L72](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs#L49-L72) + + + + + +**ESLint 以 frontend 目录为 cwd 且 reportUnusedDisableDirectives: 'error';其余规则按该 cwd 下的默认配置解析** +cwd 固定为脚本目录的上一级(frontend 根),git 与路径解析均用它;new ESLint({ cwd, reportUnusedDisableDirectives: 'error' }) 显式开启未使用 disable 指令报 error,ESLint 配置文件本身未在脚本中显式指定,由 ESLint 在该 cwd 下的默认解析决定。 + +来源:[jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs:L9–L10](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs#L9-L10), [jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs:L22–L22](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs#L22-L22) + + + + + +**依赖 git 子进程与项目内 eslint 包,路径换算受仓库布局约束** +通过 execFileSync 调 git(rev-parse/diff/ls-files/show),ESLint 类直接 import 自 'eslint' 包并以 frontend 为 cwd,因此使用 frontend 自己的 lint 配置;git diff 输出仓库相对路径而 ls-files 输出 cwd 相对路径,脚本用 prefix 剥离来统一两者。 + +来源:[jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs:L1–L5](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs#L1-L5), [jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs:L16–L22](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs#L16-L22), [jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs:L28–L31](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs#L28-L31) + + + + + +**git show 仅对'基线中不存在该路径'容错,其余 Git 错误原样抛出** +读取基线内容包在 try/catch 中:stderr 含 'does not exist in' 或 'exists on disk, but not in' 时视为新文件(previous 保持 ''),其他 Git 失败 rethrow 而不弱化检查;非 frontend 内或被 ESLint ignore 的文件直接 continue 跳过。 + +来源:[jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs:L33–L46](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs#L33-L46) + + + + + +**增量门禁放行存量诊断,但错误与警告一律拦截** +设计推断(非作者历史意图): + +收益:基线已有的诊断不阻塞本次检查(existing 计数仍可见,npm run lint 保留全量视图);成本:warnings 也会失败,且诊断按 [ruleId, severity, message] 三元组抵消——同一规则同一文案的基线诊断可抵消本次同键新增,位置变化不区分(推断:键中不含行号)。 + +来源:[jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs:L7–L8](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs#L7-L8), [jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs:L26–L26](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs#L26-L26), [jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs:L54–L61](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs#L54-L61) + + + diff --git a/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-rsi-experiment-ui.md b/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-rsi-experiment-ui.md new file mode 100644 index 00000000..4e3c624e --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-rsi-experiment-ui.md @@ -0,0 +1,62 @@ +--- +title: "RSI 自我改进实验页(创建/列表/配置回显):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/rsi/RsiPage.tsx:L28-L41, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/rsi/RsiPage.tsx:L58-L76, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/rsi/components/ConfigInfoDialog.tsx:L39-L65, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/rsi/components/CreateExperimentDialog.tsx:L105-L112, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/rsi/RsiPage.tsx:L50-L56, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/rsi/RsiPage.tsx:L78-L78, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/rsi/components/CreateExperimentDialog.tsx:L89-L107, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/rsi/components/CreateExperimentDialog.tsx:L114-L132] +feature: "rsi-experiment-ui" +entry_points: ["jiuwenswarm/channels/web/frontend/src/features/rsi/RsiPage.tsx", "jiuwenswarm/channels/web/frontend/src/features/rsi/components/ConfigInfoDialog.tsx", "jiuwenswarm/channels/web/frontend/src/features/rsi/components/CreateExperimentDialog.tsx"] +source_globs: ["jiuwenswarm/channels/web/frontend/src/features/rsi/RsiPage.tsx", "jiuwenswarm/channels/web/frontend/src/features/rsi/components/ConfigInfoDialog.tsx", "jiuwenswarm/channels/web/frontend/src/features/rsi/components/CreateExperimentDialog.tsx", "jiuwenswarm/agents/harness/common/rsi/artifact_adapter.py", "jiuwenswarm/channels/web/frontend/src/features/rsi/components/RsiDetail.tsx", "jiuwenswarm/channels/web/frontend/src/features/rsi/components/RsiRail.tsx", "jiuwenswarm/channels/web/frontend/src/features/rsi/rsiStore.ts", "jiuwenswarm/channels/web/frontend/src/features/rsi/featureConfig.ts", "jiuwenswarm/channels/web/frontend/src/features/rsi/types.ts", "jiuwenswarm/channels/web/frontend/src/features/rsi/styles/rsi.css", "jiuwenswarm/channels/web/frontend/src/features/rsi/components/RsiIntroduction.tsx", "jiuwenswarm/channels/web/frontend/src/features/rsi/mockData.ts", "jiuwenswarm/channels/web/frontend/src/features/rsi/rsiPresentation.ts", "jiuwenswarm/channels/web/frontend/src/features/rsi/components/RsiSelectedInfo.tsx", "jiuwenswarm/agents/harness/common/rsi/paper_provider.py", "jiuwenswarm/agents/harness/common/rsi/projector.py", "jiuwenswarm/channels/web/frontend/src/features/rsi/useRsiEvents.ts"] +--- + +# RSI 自我改进实验页(创建/列表/配置回显):实现深读 + +[功能概览](feature-rsi-experiment-ui.md) · [owner 入口](_index.md) + + +**RsiPage 挂载时拉取列表并自动选中第一个实验** +RsiPage 挂载后调用 rsiStore 的 loadList 拉取实验列表;当列表加载完成、未选中且 list.length > 0 时通过 selectTask 选中 list[0].task_id,页面根据 selectedTaskId 是否存在切换 RsiRail+RsiDetail 或 RsiIntroduction 布局。 + +来源:[jiuwenswarm/channels/web/frontend/src/features/rsi/RsiPage.tsx:L28–L41](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/features/rsi/RsiPage.tsx#L28-L41), [jiuwenswarm/channels/web/frontend/src/features/rsi/RsiPage.tsx:L58–L76](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/features/rsi/RsiPage.tsx#L58-L76) + + + + + +**CreateExperimentDialog 的 props 契约为 { open, onClose, onCreated },父组件用回调把新任务写入列表并选中** +CreateExperimentDialog 接收 open/onClose/onCreated 三个 props(CreateExperimentDialog.tsx:105)。RsiPage 以 createOpen 状态控制打开、onCreated 传 handleCreated:该回调对新建项调用 upsertListItem 后再 selectTask(item.task_id),onClose 时将 createOpen 置回 false。 + +来源:[jiuwenswarm/channels/web/frontend/src/features/rsi/components/CreateExperimentDialog.tsx:L105–L112](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/features/rsi/components/CreateExperimentDialog.tsx#L105-L112), [jiuwenswarm/channels/web/frontend/src/features/rsi/RsiPage.tsx:L50–L56](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/features/rsi/RsiPage.tsx#L50-L56), [jiuwenswarm/channels/web/frontend/src/features/rsi/RsiPage.tsx:L78–L78](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/features/rsi/RsiPage.tsx#L78-L78) + + + + + +**创建表单初始默认值:scenario='HARNESS'、artifactType='PAPER'、evaluationMethod='agent'、maxIterations=2** +useState(defaultForm) 以 defaultForm 作为惰性初始化器生成初始 FormState:name/optimizer/tester/datasetFile/optimizationInstruction/artifactPath/webProxy 均为空字符串,scenario 默认 HARNESS,maxIterations 默认 2。所示片段未显示对话框每次打开时重置表单的逻辑。 + +来源:[jiuwenswarm/channels/web/frontend/src/features/rsi/components/CreateExperimentDialog.tsx:L89–L107](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/features/rsi/components/CreateExperimentDialog.tsx#L89-L107) + + + + + +**按分支守卫的表单校验:HARNESS 需数据集与 tester,PAPER 需指令或路径之一,PROGRAM 必须有路径** +useMemo 在每次表单字段变化时重算 validationErrors:name 与 optimizer 必填;branch==='HARNESS' 时 datasetFile、tester 必填;branch==='PAPER' 时 optimizationInstruction 与 artifactPath 至少其一;branch==='PROGRAM' 时 artifactPath 必填。有错误时 hasValidationErrors 为真(所示片段未包含提交按钮的禁用分支)。 + +来源:[jiuwenswarm/channels/web/frontend/src/features/rsi/components/CreateExperimentDialog.tsx:L114–L132](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/features/rsi/components/CreateExperimentDialog.tsx#L114-L132) + + + + + +**配置回显按场景条件裁剪字段换取简洁,代价是信息受守卫限制** +设计推断(非作者历史意图): + +推断:ConfigInfoDialog 仅在对应守卫成立时展示字段(如 HARNESS 才显示 tester/input_file,isPaper 才显示 optimization_instruction 与 web_proxy 的已配置/未配置状态,isProgram 不显示 max_iterations),减少了无关字段,但用户在这些条件外看不到相应配置。 + +来源:[jiuwenswarm/channels/web/frontend/src/features/rsi/components/ConfigInfoDialog.tsx:L39–L65](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/features/rsi/components/ConfigInfoDialog.tsx#L39-L65) + + + diff --git a/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-share-image-export.md b/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-share-image-export.md new file mode 100644 index 00000000..5909df99 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-share-image-export.md @@ -0,0 +1,71 @@ +--- +title: "Session Share-Image Export (Job Registry + Headless Renderer):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/share_image_export.py:L86-L98, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/share_image_export.py:L101-L117, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/app_web.py:L1226-L1232, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/share_image_export.py:L44-L52, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/share_image_export.py:L210-L210, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/share_image_export.py:L69-L98, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/channels/web/test_share_image_export.py:L614-L625, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/channels/web/test_share_image_export.py:L525-L531, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/channels/web/test_share_image_export.py:L516-L522, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/share_image_export.py:L196-L208] +feature: "share-image-export" +entry_points: ["jiuwenswarm/channels/web/frontend/vite.config.ts", "jiuwenswarm/channels/web/share_image_export.py"] +source_globs: ["jiuwenswarm/channels/web/frontend/vite.config.ts", "jiuwenswarm/channels/web/share_image_export.py", "jiuwenswarm/channels/web/frontend/src/features/shareImageExport.tsx", "jiuwenswarm/channels/web/frontend/src/features/shareImageArchive.ts", "jiuwenswarm/channels/web/frontend/src/features/shareImageExport.css", "jiuwenswarm/channels/web/app_web.py", "jiuwenswarm/channels/web/frontend/src/features/shareImageJob.ts", "jiuwenswarm/channels/web/frontend/src/features/shareImagePng.worker.ts", "jiuwenswarm/channels/web/frontend/src/features/shareImagePngEncoder.ts", "jiuwenswarm/channels/web/frontend/src/App.tsx", "jiuwenswarm/channels/web/frontend/src/main.tsx", "jiuwenswarm/channels/web/frontend/src/features/shareImageRaster.ts"] +--- + +# Session Share-Image Export (Job Registry + Headless Renderer):实现深读 + +[功能概览](feature-share-image-export.md) · [owner 入口](_index.md) + + +**render_share_image keyword-only contract with module-level timeout defaults, returns Path** +render_share_image 仅接受关键字参数:必需的 base_url、job_id、output_path(Path),可选 on_phase 回调、render_auth,以及四个超时/轮询参数(init_timeout_seconds、idle_timeout_seconds、absolute_timeout_seconds、poll_interval_seconds),默认值取模块常量 _RENDER_*;函数返回 Path。 + +来源:[jiuwenswarm/channels/web/share_image_export.py:L196–L208](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/share_image_export.py#L196-L208) + + + + + +**Browser config: browser_type defaults to "auto" mapping to chrome channel; missing executable path errors** +_configured_browser resolves the first non-blank configured path key, raises RuntimeError configured_share_export_browser_not_found if that path is not a file, and browser_type (default "auto", lowercased) maps to channel "msedge" only for {msedge, edge, microsoft-edge, microsoft_edge}, otherwise "chrome"; executable_path defaults to None when unset. + +来源:[jiuwenswarm/channels/web/share_image_export.py:L86–L98](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/share_image_export.py#L86-L98) + + + + + +**render_share_image lazily imports playwright.sync_api and couples browser launch to config-resolved chrome_path/browser_type** +playwright.sync_api is imported inside render_share_image's body, so the function depends on Playwright only when invoked. _configured_browser reads resolve_env_vars(get_config())['browser'], maps a dict chrome_path by platform key (else 'default'), raises RuntimeError "configured_share_export_browser_not_found" when a resolved path is not an existing file, and derives channel "msedge" only for edge-like browser_type values, otherwise "chrome"; a missing/empty path returns (None, channel), so no executable is mandatory here. + +来源:[jiuwenswarm/channels/web/share_image_export.py:L210–L210](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/share_image_export.py#L210-L210), [jiuwenswarm/channels/web/share_image_export.py:L69–L98](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/share_image_export.py#L69-L98) + + + + + +**_validate_png_stream fails fast on truncated or malformed PNG chunks** +A stream smaller than signature+IEND, a mismatched signature, a short chunk header, or a chunk length exceeding the remaining bytes raises RuntimeError share_export_png_incomplete or share_export_png_invalid_signature; at the API layer, FileNotFoundError from snapshot building becomes 404 history_not_found and ValueError becomes 400 with the error string. + +来源:[jiuwenswarm/channels/web/share_image_export.py:L101–L117](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/share_image_export.py#L101-L117), [jiuwenswarm/channels/web/app_web.py:L1226–L1232](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/app_web.py#L1226-L1232) + + + + + +**ShareImageRenderAuth suppresses cookie_value from repr, hiding the desktop token at the cost of debuggability** +设计推断(非作者历史意图): + +cookie_value is declared field(repr=False) so the desktop access token never appears in the dataclass repr; the cost is that the token value cannot be inspected via repr when diagnosing auth issues (inference from the shown field declaration). + +来源:[jiuwenswarm/channels/web/share_image_export.py:L44–L52](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/share_image_export.py#L44-L52) + + + + + +**Automated runtime test asserts init-timeout failure path, secret non-disclosure and context closure in render_share_image** +test_render_runner_not_initialized_fails_within_init_timeout drives the real share_image_export.render_share_image via _call_render with a faked playwright module and _configured_browser monkeypatched to (None, "chrome"), and asserts pytest.raises(RuntimeError, match="share_export_runner_not_initialized"), elapsed < 5 seconds, "desktop-secret" absent from the exception text, and harness.context.closed. + +来源:[tests/unit_tests/channels/web/test_share_image_export.py:L614–L625](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/channels/web/test_share_image_export.py#L614-L625), [tests/unit_tests/channels/web/test_share_image_export.py:L525–L531](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/channels/web/test_share_image_export.py#L525-L531), [tests/unit_tests/channels/web/test_share_image_export.py:L516–L522](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/channels/web/test_share_image_export.py#L516-L522) + + + diff --git a/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-web-asset-publish-flow.md b/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-web-asset-publish-flow.md new file mode 100644 index 00000000..8a9ce3fa --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-web-asset-publish-flow.md @@ -0,0 +1,71 @@ +--- +title: "Web 资产发布流程(prepare/commit/轮询/提交锁):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/services/assetPublishApi.ts:L28-L38, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/hooks/useAssetPublish.ts:L39-L61, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/assetPublishState.ts:L7-L15, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/assetPublishState.ts:L47-L61, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/assetPublishErrors.ts:L13-L33, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/tests/assetPublishDrawer.test.mjs:L317-L331, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/assetPublishEvents.ts:L1-L4, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/services/assetPublishApi.ts:L10-L38, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/assetPublishState.ts:L23-L41] +feature: "web-asset-publish-flow" +entry_points: ["jiuwenswarm/channels/web/frontend/src/hooks/useAssetPublish.ts"] +source_globs: ["jiuwenswarm/channels/web/frontend/src/hooks/useAssetPublish.ts", "jiuwenswarm/channels/web/frontend/src/types/assetPublish.ts", "jiuwenswarm/channels/web/frontend/src/features/assetPublication.ts", "jiuwenswarm/channels/web/frontend/src/features/assetPublishErrors.ts", "jiuwenswarm/channels/web/frontend/src/features/assetPublishEvents.ts", "jiuwenswarm/channels/web/frontend/src/features/assetPublishState.ts"] +--- + +# Web 资产发布流程(prepare/commit/轮询/提交锁):实现深读 + +[功能概览](feature-web-asset-publish-flow.md) · [owner 入口](_index.md) + + +**updateSubmission 回调按活动提交过滤记录并设置提交锁** +useAssetPublish 的 updateSubmission 回调:若已有 activeSubmission 且其 operationId/draftId 均不匹配 next,则返回 false 不更新;否则按 publishOutcome 是否为 queued/uploading/unknown 设置 activeSubmission 与 submissionLocked,并把记录去重前插到 records。record 相关字段变化时通过 window 事件 'asset-publication-changed' 通知。 + +来源:[jiuwenswarm/channels/web/frontend/src/hooks/useAssetPublish.ts:L39–L61](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/hooks/useAssetPublish.ts#L39-L61), [jiuwenswarm/channels/web/frontend/src/features/assetPublishState.ts:L7–L15](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/features/assetPublishState.ts#L7-L15) + + + + + +**assetPublishApi.commit 接受 (draft_id, request_id);prepare 传 metadata、可选 target_asset_id 与 force** +commit 调用 request('commit', {draft_id, request_id}) 返回 PublishRecord;prepare 过滤空 tags,target_asset_id 仅在非空时携带,并显式传 force。调用方须提供幂等 request_id。 + +来源:[jiuwenswarm/channels/web/frontend/src/services/assetPublishApi.ts:L28–L38](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/services/assetPublishApi.ts#L28-L38) + + + + + +**发布 RPC 默认 75 秒超时,localStatus 单独用 15 秒且不带 auth** +describe/prepare/commit/status/records 经共享 request 助手走 `assets.publish.*` 并统一注入 auth 与 `{ timeoutMs: 75_000 }`;仅 localStatus 直接调 webRequest,超时 15_000 且参数只含引用字段。 + +来源:[jiuwenswarm/channels/web/frontend/src/services/assetPublishApi.ts:L10–L38](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/services/assetPublishApi.ts#L10-L38) + + + + + +**definitiveCommitRejection 区分 'expired'/'rejected',publishIssueKey 未知错误回落 'requestFailed'** +definitiveCommitRejection 仅在 code/message 字符串匹配 \bdraft_expired\b(不区分大小写)时返回 'expired',匹配 invalid_draft、draft_not_found、publish_auth_required、auth_required、invalid_identifier、queue_full、target_conflict 时返回 'rejected',否则 null。publishIssueKey 将错误码规范化(trim、'-'→'_'、大写)后查 SAFE_FAILURE_KEYS 白名单,未命中回落 'requestFailed'。 + +来源:[jiuwenswarm/channels/web/frontend/src/features/assetPublishState.ts:L47–L61](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/features/assetPublishState.ts#L47-L61), [jiuwenswarm/channels/web/frontend/src/features/assetPublishErrors.ts:L13–L33](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/features/assetPublishErrors.ts#L13-L33) + + + + + +**createCommitAttempt 并发去重换取固定 requestId 重试:成功结果被缓存,失败后会重新 send** +设计推断(非作者历史意图): + +收益:同一 attempt 实例内并发的 run() 共享同一个 pending Promise,成功后 completed 缓存让后续 run 直接返回已兑现值。成本:仅成功结果被缓存——send 拒绝后 finally 清空 pending,之后的 run 会用同一 requestId 再次调用 send,客户端本身并不阻止重复提交(推断:去重依赖服务端按 request_id 幂等)。 + +来源:[jiuwenswarm/channels/web/frontend/src/features/assetPublishState.ts:L23–L41](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/features/assetPublishState.ts#L23-L41) + + + + + +**抽屉测试用桩 API 验证轮询完成后更新历史行(automated_runtime)** +assetPublishDrawer.test.mjs 用 assetPublishApi.describe/status 桩返回 queued→completed/pending_moderation,openAssetPublish 打开抽屉后等待约 2100ms,断言 'asset-publish-record' 文本匹配 /pending moderation/i。这是对抽屉运行时行为的自动化测试(API 已打桩),非本批内执行的声明。 + +来源:[jiuwenswarm/channels/web/frontend/tests/assetPublishDrawer.test.mjs:L317–L331](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/tests/assetPublishDrawer.test.mjs#L317-L331), [jiuwenswarm/channels/web/frontend/src/features/assetPublishEvents.ts:L1–L4](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/features/assetPublishEvents.ts#L1-L4) + + + diff --git a/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-web-i18n-zh-en.md b/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-web-i18n-zh-en.md new file mode 100644 index 00000000..258e6cc4 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-web-i18n-zh-en.md @@ -0,0 +1,71 @@ +--- +title: "Web 前端中英双语 i18n 初始化:实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/i18n/index.ts:L15-L27, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/i18n/index.ts:L1-L14, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/i18n/index.ts:L22-L27, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/i18n/index.ts:L1-L28, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/i18n/index.ts:L30-L30, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/tests/fixtures/settings-extension/extensionDemoMain.tsx:L17-L20, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/i18n/index.ts:L15-L28] +feature: "web-i18n-zh-en" +entry_points: ["jiuwenswarm/channels/web/frontend/src/i18n/index.ts"] +source_globs: ["jiuwenswarm/channels/web/frontend/src/i18n/index.ts", "jiuwenswarm/channels/web/frontend/src/App.tsx"] +--- + +# Web 前端中英双语 i18n 初始化:实现深读 + +[功能概览](feature-web-i18n-zh-en.md) · [owner 入口](_index.md) + + +**模块导入时链式注册插件并调用 init(配置结果未在所示行内确认)** +导入 i18next 实例后依次 .use(LanguageDetector)、.use(initReactI18next),再以 zh/en 两个 translation 资源调用 init,完成语言检测与 React 绑定的配置;init 是否同步完成未在所示行内展示。 + +来源:[jiuwenswarm/channels/web/frontend/src/i18n/index.ts:L1–L28](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/i18n/index.ts#L1-L28) + + + + + +**契约仅为默认导出该 i18n 实例;扩展方可对 zh/en 追加 translation 资源包** +模块默认导出已配置的 i18n 实例(L30)。fixture 演示调用方用法:对 ['zh','en'] 逐语言 addResourceBundle(language, 'translation', bundle, true, false),随后以 i18n.exists(key,{lng}) 校验两种语言键是否存在。 + +来源:[jiuwenswarm/channels/web/frontend/src/i18n/index.ts:L30–L30](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/i18n/index.ts#L30-L30), [jiuwenswarm/channels/web/frontend/tests/fixtures/settings-extension/extensionDemoMain.tsx:L17–L20](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/tests/fixtures/settings-extension/extensionDemoMain.tsx#L17-L20) + + + + + +**detection 仅用 localStorage,未检出时默认中文** +detection.order 与 caches 均为 ['localStorage'],不支持 navigator;fallbackLng: 'zh',supportedLngs: ['zh','en'],interpolation.escapeValue 为 false。即首次无 localStorage 的访客固定得到中文。 + +来源:[jiuwenswarm/channels/web/frontend/src/i18n/index.ts:L15–L27](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/i18n/index.ts#L15-L27) + + + + + +**i18next + react-i18next + i18next-browser-languagedetector 三件套** +LanguageDetector 只负责 localStorage 检测(order 限定),initReactI18next 挂接 React;语言资源静态来自 ./locales/zh.json 与 en.json,随模块导入打包。 + +来源:[jiuwenswarm/channels/web/frontend/src/i18n/index.ts:L1–L14](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/i18n/index.ts#L1-L14) + + + + + +**localStorage 未缓存语言时的回退:fallbackLng 为 zh** +detection.order 仅含 'localStorage'(L25),不会读取 navigator;注释(L23–L24)说明未手动选择语言时默认中文。结合 init 的 fallbackLng: 'zh'(L17),当 localStorage 中没有已缓存的语言时,初始化结果落在 zh 资源上。supportedLngs 限定为 ['zh','en'](L18)。 + +来源:[jiuwenswarm/channels/web/frontend/src/i18n/index.ts:L15–L28](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/i18n/index.ts#L15-L28) + + + + + +**放弃 navigator 检测:避免英文闪烁 vs 牺牲浏览器语言偏好** +设计推断(非作者历史意图): + +(推断)收益:注释写明桌面 WebView2 常为 en-US,不用 navigator 可避免启动初期误显英文,且与后端 preferred_language 默认一致;代价:无 localStorage 的英文浏览器用户首次访问也会看到中文,需手动切换。 + +来源:[jiuwenswarm/channels/web/frontend/src/i18n/index.ts:L22–L27](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/i18n/index.ts#L22-L27) + + + diff --git a/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-web-native-directory-picker.md b/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-web-native-directory-picker.md new file mode 100644 index 00000000..a71acff8 --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-web-native-directory-picker.md @@ -0,0 +1,53 @@ +--- +title: "Web 通道本机目录/可执行文件选择器(跨平台后端链):实现深读" +created: 2026-10-06 +updated: 2026-10-06 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/directory_picker.py:L296-L309, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/directory_picker.py:L427-L443, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/directory_picker.py:L290-L295, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/directory_picker.py:L339-L346, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/directory_picker.py:L501-L520] +feature: "web-native-directory-picker" +entry_points: ["jiuwenswarm/channels/web/directory_picker.py"] +source_globs: ["jiuwenswarm/channels/web/directory_picker.py"] +--- + +# Web 通道本机目录/可执行文件选择器(跨平台后端链):实现深读 + +[功能概览](feature-web-native-directory-picker.md) · [owner 入口](_index.md) + + +**select_file_native(*, initial_dir=None, title=None):title 为 None 或全空白时回退 _FILE_DIALOG_TITLE,调用方自行校验文件可用性** +入口先经 _resolve_initial_dir 得到 start_dir;dialog_title 仅当传入的 title 是非空白字符串时取其 strip() 结果,否则用模块常量 _FILE_DIALOG_TITLE。随后按 sys.platform 分派:win32→_select_file_windows_tk,darwin→_select_file_macos,linux 前缀→_select_file_linux,其余平台直接抛 RuntimeError。docstring 明确调用方负责验证所选文件在其领域是否为可用可执行文件。 + +来源:[jiuwenswarm/channels/web/directory_picker.py:L501–L520](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/directory_picker.py#L501-L520) + + + + + +**tkinter 子进程用环境变量传参,initial 默认 ~,title 默认 Select Directory** +_try_tkinter_subprocess 通过 JIUWEN_DIR_PICKER_INITIAL 和 JIUWEN_DIR_PICKER_TITLE 环境变量传参;子进程内 initial 缺省为 expanduser("~"),title 缺省为 "Select Directory"。 + +来源:[jiuwenswarm/channels/web/directory_picker.py:L296–L309](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/directory_picker.py#L296-L309) + + + + + +**后端异常记录后继续;TimeoutExpired 立即中止;全部失败抛 RuntimeError** +循环中除 subprocess.TimeoutExpired(转为 RuntimeError "directory picker timed out" 并中止)外的异常记入 errors 并尝试下一 backend;全部失败时抛 RuntimeError,消息含各 backend 错误与 "fallback to typing an absolute path in the UI" 提示。 + +来源:[jiuwenswarm/channels/web/directory_picker.py:L427–L443](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/directory_picker.py#L427-L443) + + + + + +**独立子进程跑 tkinter:换来线程安全,付出进程启动与 600s 超时代价** +设计推断(非作者历史意图): + +docstring 声明在独立子进程中运行 tkinter 以保证 Tk 位于该进程主线程、可从 asyncio.to_thread 工作线程安全调用(收益);代价是每次选择都启动一个 Python 子进程,且受 timeout=600.0 约束(此为标注的实现内推断)。 + +来源:[jiuwenswarm/channels/web/directory_picker.py:L290–L295](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/directory_picker.py#L290-L295), [jiuwenswarm/channels/web/directory_picker.py:L339–L346](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/directory_picker.py#L339-L346) + + + From 2d54c48fe31f83df298dec94a26e8fea30d8c95d Mon Sep 17 00:00:00 2001 From: tzhouam Date: Wed, 7 Oct 2026 18:22:22 +0800 Subject: [PATCH 3/5] Retain audited Jiuwen depth additions for targeted validation evidence --- ...epth-runtime-agent-definition-execution.md | 11 +++- .../feature-depth-command-execution-tool.md | 13 +++- .../feature-depth-llm-wiki-knowledge-base.md | 13 +++- .../feature-depth-pdf-reading-tool.md | 20 +++++- .../feature-depth-sdd-design-rail.md | 11 +++- .../feature-depth-user-todos-tool.md | 11 +++- .../feature-depth-web-search-tools.md | 11 +++- .../feature-depth-xiaoyi-calendar-tools.md | 11 +++- .../feature-depth-xiaoyi-call-phone-tool.md | 11 +++- .../feature-depth-xiaoyi-collection-tools.md | 20 +++++- .../feature-depth-xiaoyi-location-tool.md | 11 +++- .../feature-depth-xiaoyi-note-tools.md | 22 ++++++- ...eature-depth-xiaoyi-photo-gallery-tools.md | 11 +++- ...-depth-xiaoyi-pushdata-store-and-viewer.md | 11 +++- ...eature-depth-xiaoyi-save-to-phone-tools.md | 20 +++++- ...depth-agent-template-layered-validation.md | 22 ++++++- .../feature-depth-arxiv-visual-extraction.md | 31 +++++++++- ...ure-depth-ascend-chrome-trace-generator.md | 33 +++++++++- ...depth-ascend-trace-auto-instrumentation.md | 31 +++++++++- ...pth-ascend-trace-compile-safety-checker.md | 13 +++- ...th-ascend-trace-instrumentation-planner.md | 22 ++++++- ...ture-depth-audit-integrity-hmac-signing.md | 24 ++++++- ...eature-depth-audit-report-html-renderer.md | 33 +++++++++- ...epth-cross-channel-history-search-skill.md | 22 ++++++- .../feature-depth-daily-report-skill.md | 13 +++- .../feature-depth-docx-pro-cli.md | 22 ++++++- ...feature-depth-financial-document-parser.md | 13 +++- ...ature-depth-huawei-maas-apikey-creation.md | 13 +++- ...feature-depth-huawei-maas-cdp-authorize.md | 13 +++- .../feature-depth-local-doc-ocr-offline.md | 22 ++++++- .../feature-depth-maas-auto-open-models.md | 22 ++++++- .../feature-depth-opc-add-slide.md | 11 +++- ...eature-depth-plugin-package-initializer.md | 31 +++++++++- .../feature-depth-ppt-deck-finalize.md | 13 +++- .../feature-depth-ppt-evidence-preparation.md | 24 ++++++- ...ture-depth-ppt-execution-lock-validator.md | 24 ++++++- .../feature-depth-ppt-figure-panel-layout.md | 20 +++++- .../feature-depth-ppt-opc-thumbnail.md | 22 ++++++- .../feature-depth-pptx-structural-audit.md | 22 ++++++- .../feature-depth-rsi-dataset-folder-check.md | 11 +++- .../feature-depth-skill-generator-cli.md | 31 +++++++++- .../feature-depth-skill-page-scrape-blocks.md | 13 +++- .../feature-depth-sop-structure-extraction.md | 40 +++++++++++- .../feature-depth-xlsx-add-computed-column.md | 13 +++- .../feature-depth-xlsx-doctor-selfcheck.md | 22 ++++++- .../feature-depth-xlsx-formula-check.md | 13 +++- .../feature-depth-xlsx-insert-row.md | 11 +++- ...ature-depth-xlsx-reader-structural-diff.md | 13 +++- ...-depth-agentos-sandbox-create-lifecycle.md | 20 +++++- ...-depth-video-agent-managed-task-service.md | 11 +++- ...ture-depth-yuanrong-agent-file-transfer.md | 13 +++- .../feature-depth-yuanrong-faas-invocation.md | 40 +++++++++++- ...h-channel-security-review-slash-command.md | 11 +++- ...feature-depth-gateway-config-hot-reload.md | 11 +++- .../feature-depth-gateway-health-check.md | 11 +++- ...ure-depth-gateway-server-multi-route-ws.md | 20 +++++- ...pth-im-attachment-persist-hook-969909e1.md | 20 +++++- .../feature-depth-im-channel-hot-reconfig.md | 11 +++- .../feature-depth-im-feishu.md | 13 +++- .../feature-depth-ide-file-edit-diff-apply.md | 33 +++++++++- .../feature-depth-ide-turn-rewind-snapshot.md | 22 ++++++- ...ture-depth-chat-session-stats-dashboard.md | 22 ++++++- ...feature-depth-code-mode-branch-selector.md | 11 +++- .../feature-depth-code-mode-commit-push.md | 13 +++- .../feature-depth-context-usage-indicator.md | 22 ++++++- .../feature-depth-dev-ws-traffic-logger.md | 62 +++++++++++++++++++ ...re-depth-frontend-incremental-lint-gate.md | 11 +++- .../feature-depth-rsi-experiment-ui.md | 11 +++- .../feature-depth-share-image-export.md | 11 +++- .../feature-depth-web-asset-publish-flow.md | 11 +++- .../feature-depth-web-i18n-zh-en.md | 11 +++- ...ature-depth-web-native-directory-picker.md | 29 ++++++++- 72 files changed, 1269 insertions(+), 71 deletions(-) create mode 100644 knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-dev-ws-traffic-logger.md diff --git a/knowledge/repos/jiuwenswarm/components/agent-runtime/feature-depth-runtime-agent-definition-execution.md b/knowledge/repos/jiuwenswarm/components/agent-runtime/feature-depth-runtime-agent-definition-execution.md index bb28be7a..c1649dec 100644 --- a/knowledge/repos/jiuwenswarm/components/agent-runtime/feature-depth-runtime-agent-definition-execution.md +++ b/knowledge/repos/jiuwenswarm/components/agent-runtime/feature-depth-runtime-agent-definition-execution.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/agent_definition.py:L159-L174, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/agent_definition.py:L117-L122, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/agent_definition.py:L161-L166, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/agent_definition.py:L288-L301, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/agent_definition.py:L304-L316, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/runtime/test_agent_definition.py:L41-L50, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/agent_definition.py:L265-L274, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/agent_definition.py:L319-L326, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/agent_definition.py:L276-L286, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/agent_definition.py:L252-L262, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/runtime/test_agent_definition.py:L244-L253, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/runtime/test_agent_definition.py:L277-L285] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/agent_definition.py:L159-L174, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/agent_definition.py:L117-L122, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/agent_definition.py:L161-L166, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/agent_definition.py:L288-L301, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/agent_definition.py:L304-L316, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/runtime/test_agent_definition.py:L41-L50, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/agent_definition.py:L265-L274, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/agent_definition.py:L319-L326, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/agent_definition.py:L276-L286, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/agent_definition.py:L252-L262, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/runtime/test_agent_definition.py:L244-L253, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/runtime/test_agent_definition.py:L277-L285, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/service.py:L1281-L1308] feature: "runtime-agent-definition-execution" entry_points: ["jiuwenswarm/runtime/service.py"] source_globs: ["jiuwenswarm/runtime/service.py", "jiuwenswarm/runtime/agent_definition.py"] @@ -69,3 +69,12 @@ test_work_modes_return_stable_unsupported_error 对两个 WORK mode 断言 AGENT + + +**stream_agent 入口:校验并改写定义后委托既有 stream 链** +stream_agent 先 await self.start() 并做会话归属校验;当 request.params 是 dict 时取其中的 mode 经 resolve_mode_capability 解析,再 validate_agent_definition 得到 execution,随后 _bind_agent_execution_request 改写请求并 await _claim_agent_execution_owner 绑定 owner,最后在 aclosing 中把 bound_request 连同 _agent_execution=execution 透传给 self.stream,逐个 yield 事件。 + +来源:[jiuwenswarm/runtime/service.py:L1281–L1308](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/runtime/service.py#L1281-L1308) + + + diff --git a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-command-execution-tool.md b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-command-execution-tool.md index cd18a6bb..5db8e054 100644 --- a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-command-execution-tool.md +++ b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-command-execution-tool.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/command_tools.py:L1099-L1139, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/command_execution_context.py:L10-L42, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/command_execution_context.py:L57-L60, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/command_tools.py:L878-L884, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/command_runtime.py:L35-L60, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/command_tools.py:L1124-L1127, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/agents/test_command_tools_sandbox.py:L156-L168, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/agents/test_command_tools_sandbox.py:L56-L57, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/agents/test_command_tools_sandbox.py:L66-L104, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/command_tools.py:L20-L36] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/command_tools.py:L1099-L1139, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/command_execution_context.py:L10-L42, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/command_execution_context.py:L57-L60, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/command_tools.py:L878-L884, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/command_runtime.py:L35-L60, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/command_tools.py:L1124-L1127, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/agents/test_command_tools_sandbox.py:L156-L168, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/agents/test_command_tools_sandbox.py:L56-L57, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/agents/test_command_tools_sandbox.py:L66-L104, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/command_tools.py:L20-L36, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/command_tools.py:L903-L913] feature: "command-execution-tool" entry_points: ["jiuwenswarm/agents/harness/common/tools/command_tools.py"] source_globs: ["jiuwenswarm/agents/harness/common/tools/command_tools.py", "jiuwenswarm/agents/harness/common/tools/command_execution_context.py", "jiuwenswarm/agents/harness/common/tools/command_runtime.py"] @@ -67,3 +67,14 @@ test_bound_sandbox_foreground_never_uses_host_subprocess 通过 mcp_exec_command + + +**轮询中即时取消检查的收益与 0.1 秒休眠成本(仅限未抛出的迭代)** +设计推断(非作者历史意图): + +收益(推断):在进程运行期间,只要 sid 为真且 consume_shell_session_cancelled(sid) 返回真,循环先检查 deadline、再终止进程并抛出 CommandCancelled(L903–L912),使取消能在长命令中及时生效。成本(推断):仅当该次迭代未触发超时(L904–L906)也未命中取消(L910–L912)而继续执行时,才调用 time.sleep(0.1)(L913)进入下一轮。 + +来源:[jiuwenswarm/agents/harness/common/tools/command_tools.py:L903–L913](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/command_tools.py#L903-L913) + + + diff --git a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-llm-wiki-knowledge-base.md b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-llm-wiki-knowledge-base.md index d03f8186..8de9c723 100644 --- a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-llm-wiki-knowledge-base.md +++ b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-llm-wiki-knowledge-base.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L536-L556, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L398-L415, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L42-L43, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L445-L459, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L20-L21, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L539-L558, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L569-L591, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/agents/test_wiki_tools_runtime_config.py:L30-L74, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L530-L558] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L536-L556, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L398-L415, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L42-L43, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L445-L459, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L20-L21, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L539-L558, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L569-L591, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/agents/test_wiki_tools_runtime_config.py:L30-L74, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L530-L558, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L313-L325, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L462-L466] feature: "llm-wiki-knowledge-base" entry_points: ["jiuwenswarm/agents/harness/common/tools/wiki_tools.py"] source_globs: ["jiuwenswarm/agents/harness/common/tools/wiki_tools.py"] @@ -67,3 +67,14 @@ test_create_llm_wiki_propagates_runtime_policy_and_parent_lineage 用 monkeypatc + + +**ingest 默认 force=False:已知 SHA-256 直接跳过,需显式 force=True 才重新摄取** +设计推断(非作者历史意图): + +默认 force=False 时,若 manifest 已识别该文件的 SHA-256,ingest 记 warning 并返回 skipped 结果而不重新处理(推断)收益是相同内容不重复摄取,代价是调用方必须显式传 force=True 才会重跑。 + +来源:[jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L313–L325](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/wiki_tools.py#L313-L325), [jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L462–L466](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/wiki_tools.py#L462-L466) + + + diff --git a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-pdf-reading-tool.md b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-pdf-reading-tool.md index d77d7d1e..432593fc 100644 --- a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-pdf-reading-tool.md +++ b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-pdf-reading-tool.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L24-L26, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L117-L122, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L143-L143, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/agents/test_pdf_tools.py:L146-L159, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L239-L262, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L263-L275, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L125-L130, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L92-L101, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L143-L163, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L201-L208] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L24-L26, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L117-L122, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L143-L143, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/agents/test_pdf_tools.py:L146-L159, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L239-L262, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L263-L275, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L125-L130, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L92-L101, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L143-L163, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L201-L208, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L86-L109, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L112-L116, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L274-L275, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L257-L275, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L112-L122, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L125-L145] feature: "pdf-reading-tool" entry_points: ["jiuwenswarm/agents/harness/common/tools/pdf_tools.py"] source_globs: ["jiuwenswarm/agents/harness/common/tools/pdf_tools.py"] @@ -60,3 +60,21 @@ test_read_pdf_extracts_pages_and_flags_blank 构造 3 页 PDF 后 await read_pdf + + +**read_pdf 归一化入参后经 asyncio.to_thread 执行同步提取,异常转为错误字符串返回** +async 入口 read_pdf 将三个入参交给 _normalize_request:pdf_path 去首尾空白后为空即抛 ValueError;max_chars 先按 int() 转换,仅在转换抛出 TypeError 或 ValueError 时回退 DEFAULT_MAX_CHARS,再被夹在 [1_000, _MAX_CHARS_CEILING] 区间。随后 logger.info 记录归一化后的 path/pages/max_chars,并通过 asyncio.to_thread 把 _read_pdf_sync 卸载到线程;该同步函数先调用 _resolve_pdf_path 校验路径,再 import pdfplumber 并 open 文件,按 total_pages 过滤出 selected 页(超出总页数的请求页归入 out_of_range),selected 再被截断到 _MAX_PAGES_PER_CALL,随后开始构造 header 字符串。以上任何一步抛出的 Exception 都被 read_pdf 的 except 捕获,函数返回字符串 "[ERROR]: read_pdf failed: {exc}"。 + +来源:[jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L257–L275](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/pdf_tools.py#L257-L275), [jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L112–L122](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/pdf_tools.py#L112-L122), [jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L125–L145](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/pdf_tools.py#L125-L145) + + + + + +**路径/规整阶段抛出的 ValueError 与 FileNotFoundError 在 read_pdf 内被 except Exception 转为错误字符串返回** +_resolve_pdf_path 对空值抛 ValueError("pdf_path cannot be empty"),相对路径在 get_workspace() 失败或为空时抛 ValueError("read_pdf runtime workspace is unavailable"),文件不存在抛 FileNotFoundError,非文件或后缀非 .pdf 抛 ValueError;_normalize_request 对空 pdf_path 抛 ValueError。这些异常在 read_pdf 的 except Exception 分支被捕获并作为字符串 "[ERROR]: read_pdf failed: {exc}" 返回给调用者;该分支仅捕获 Exception,不代表所有可抛对象都被转换。 + +来源:[jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L86–L109](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/pdf_tools.py#L86-L109), [jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L112–L116](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/pdf_tools.py#L112-L116), [jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L274–L275](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/pdf_tools.py#L274-L275) + + + diff --git a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-sdd-design-rail.md b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-sdd-design-rail.md index efa4c400..13daca6a 100644 --- a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-sdd-design-rail.md +++ b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-sdd-design-rail.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py:L76-L92, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py:L91-L92, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/sdd/design_rail/test_config_loader.py:L46-L47, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/sdd/design_rail/test_config_loader.py:L76-L83, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/sdd/design_rail/test_design_rail_integration.py:L121-L127, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py:L62-L92, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/code/rails/sdd/common/rail_state_machine.py:L40-L51, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py:L85-L90, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/code/rails/sdd/common/rail_state_machine.py:L261-L264, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py:L140-L149] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py:L76-L92, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py:L91-L92, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/sdd/design_rail/test_config_loader.py:L46-L47, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/sdd/design_rail/test_config_loader.py:L76-L83, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/sdd/design_rail/test_design_rail_integration.py:L121-L127, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py:L62-L92, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/code/rails/sdd/common/rail_state_machine.py:L40-L51, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py:L85-L90, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/code/rails/sdd/common/rail_state_machine.py:L261-L264, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py:L140-L149, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py:L97-L149, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py:L186-L207] feature: "sdd-design-rail" entry_points: ["jiuwenswarm/agents/harness/code/rails/sdd/common/rail_state_machine.py", "jiuwenswarm/agents/harness/code/rails/sdd/design_rail/__init__.py", "jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py"] source_globs: ["jiuwenswarm/agents/harness/code/rails/sdd/common/rail_state_machine.py", "jiuwenswarm/agents/harness/code/rails/sdd/design_rail/__init__.py", "jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py", "jiuwenswarm/agents/harness/code/rails/sdd/design_rail/skills/aet-req-analysis/scripts/assemble-checklist.mjs", "jiuwenswarm/agents/harness/code/rails/sdd/design_rail/skills/aet-req-analysis/scripts/assemble-template.mjs", "jiuwenswarm/agents/harness/code/rails/sdd/design_rail/skills/aet-req-design/scripts/assemble-checklist.mjs", "jiuwenswarm/agents/harness/code/rails/sdd/design_rail/skills/aet-req-design/scripts/assemble-template.mjs", "jiuwenswarm/agents/harness/code/rails/sdd/design_rail/config_loader.py", "jiuwenswarm/agents/harness/code/rails/sdd/__init__.py", "jiuwenswarm/agents/harness/code/rails/sdd/common/__init__.py"] @@ -69,3 +69,12 @@ __init__ 中 validate 结果不 ok 时 raise ValueError(含 errors 列表) + + +**ask_user 回调在评审阶段对拒绝答案按 _rework_target 查表结果条件转移,批准则仅等待显式 sdd_advance** +after_tool_call 回调先取 ctx.inputs 的 tool_name,非 ask_user 直接返回;随后在 stage 为 done、stage 不在 _REWORK_TARGETS 键集或 answer 文本为空时跳过转移。对非空答案,_is_reject 用 _REJECT_PATTERNS 正则与 _REJECT_CJK 关键词判定拒绝;拒绝且 _rework_target(即 _REWORK_TARGETS.get(stage))返回非 None 时调用 _transition_to(target)。批准分支不自动转移,仅记录日志并等待 agent 显式调用 sdd_advance。 + +来源:[jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py:L97–L149](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py#L97-L149), [jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py:L186–L207](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py#L186-L207) + + + diff --git a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-user-todos-tool.md b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-user-todos-tool.md index 475b07ce..0338f5f3 100644 --- a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-user-todos-tool.md +++ b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-user-todos-tool.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/user_todo_tool.py:L17-L19, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/user_todo_tool.py:L109-L124, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/user_todo_tool.py:L270-L305, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/user_todo_tool.py:L208-L230, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/user_todo_tool.py:L246-L253, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/user_todo_tool.py:L13-L14, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/user_todo_tool.py:L194-L207, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/user_todo_tool.py:L114-L124] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/user_todo_tool.py:L17-L19, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/user_todo_tool.py:L109-L124, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/user_todo_tool.py:L270-L305, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/user_todo_tool.py:L208-L230, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/user_todo_tool.py:L246-L253, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/user_todo_tool.py:L13-L14, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/user_todo_tool.py:L194-L207, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/user_todo_tool.py:L114-L124, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/user_todo_tool.py:L255-L263, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/user_todo_tool.py:L384-L395] feature: "user-todos-tool" entry_points: ["jiuwenswarm/agents/harness/common/tools/user_todo_tool.py"] source_globs: ["jiuwenswarm/agents/harness/common/tools/user_todo_tool.py"] @@ -60,3 +60,12 @@ Benefit: _sanitize_channel_id strips path separators and special characters, pre + + +**get with missing todo_id returns success:false; any Exception is caught and converted to an error dict** +在 _handle_user_todos 的 get 分支中,params.todo_id 为空时本地返回 {"success": False, "error": "todo_id is required for get action"};整个 action 分发的 try 中任何 Exception 都被 L390–L395 的 except 捕获,记录日志后返回 {"success": False, "error": str(e)},不向调用方抛出。 + +来源:[jiuwenswarm/agents/harness/common/tools/user_todo_tool.py:L255–L263](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/user_todo_tool.py#L255-L263), [jiuwenswarm/agents/harness/common/tools/user_todo_tool.py:L384–L395](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/user_todo_tool.py#L384-L395) + + + diff --git a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-web-search-tools.md b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-web-search-tools.md index 566c3fa7..7f6e79e2 100644 --- a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-web-search-tools.md +++ b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-web-search-tools.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/trusted_search_tool_adapter.py:L36-L71, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/trusted_search_tool_adapter.py:L57-L66, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/agentserver/permissions/test_trusted_search_tool_adapter.py:L178-L186, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/agentserver/permissions/test_trusted_search_tool_adapter.py:L135-L151, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/agentserver/permissions/test_trusted_search_tool_adapter.py:L190-L216, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/agentserver/permissions/test_trusted_search_tool_adapter.py:L219-L240, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/search_tools.py:L31-L33, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/search_tools.py:L534-L548, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/search_tools.py:L31-L39, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/trusted_search_tool_adapter.py:L36-L48, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/trusted_search_tool_adapter.py:L82-L99, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/trusted_search_tool_adapter.py:L110-L114, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/search_tools.py:L565-L583] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/trusted_search_tool_adapter.py:L36-L71, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/trusted_search_tool_adapter.py:L57-L66, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/agentserver/permissions/test_trusted_search_tool_adapter.py:L178-L186, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/agentserver/permissions/test_trusted_search_tool_adapter.py:L135-L151, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/agentserver/permissions/test_trusted_search_tool_adapter.py:L190-L216, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/agentserver/permissions/test_trusted_search_tool_adapter.py:L219-L240, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/search_tools.py:L31-L33, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/search_tools.py:L534-L548, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/search_tools.py:L31-L39, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/trusted_search_tool_adapter.py:L36-L48, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/trusted_search_tool_adapter.py:L82-L99, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/trusted_search_tool_adapter.py:L110-L114, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/search_tools.py:L565-L583, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/trusted_search_tool_adapter.py:L18-L29, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/trusted_search_tool_adapter.py:L100-L109, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/search_tools.py:L565-L585] feature: "web-search-tools" entry_points: ["jiuwenswarm/agents/harness/common/tools/trusted_search_tool_adapter.py"] source_globs: ["jiuwenswarm/agents/harness/common/tools/trusted_search_tool_adapter.py", "jiuwenswarm/channels/web/frontend/src/features/settings/modules/agent/AgentSettings.tsx", "jiuwenswarm/channels/web/frontend/src/features/settings/modules/agent/definition.ts", "jiuwenswarm/agents/harness/common/tools/search_tools.py"] @@ -69,3 +69,12 @@ test_free_adapter_runs_normally_without_provenance_lease (lines 135-151) monkeyp + + +**Adapter imports search helpers and trusted-search producer; paid-search ordering rechecks configured providers** +trusted_search_tool_adapter.py imports complete_trusted_search_producer from the trusted_search_urls permissions module and seven names (including the constant DEFAULT_SEARCH_MAX_RESULTS and the run/render helpers) from search_tools; on paid-search success it calls complete_trusted_search_producer(tool_name="mcp_paid_search", success=True, urls=urls) before returning render_paid_search_result. In search_tools, run order prefers the requested provider only if it is in configured_paid_search_providers(), otherwise falls back to that configured list, and each loop iteration re-checks configured_paid_search_providers() so queued calls skip providers whose keys were removed. Consequence: the adapter delegates execution/rendering and lease completion to these imports rather than reimplementing them. + +来源:[jiuwenswarm/agents/harness/common/tools/trusted_search_tool_adapter.py:L18–L29](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/trusted_search_tool_adapter.py#L18-L29), [jiuwenswarm/agents/harness/common/tools/trusted_search_tool_adapter.py:L100–L109](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/trusted_search_tool_adapter.py#L100-L109), [jiuwenswarm/agents/harness/common/tools/search_tools.py:L565–L585](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/search_tools.py#L565-L585) + + + diff --git a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-calendar-tools.md b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-calendar-tools.md index 83c046dd..020d8089 100644 --- a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-calendar-tools.md +++ b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-calendar-tools.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L113-L129, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L137-L164, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L166-L173, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L137-L160, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L244-L256, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L219-L229, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L265-L267, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L198-L207, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L210-L228, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L121-L125, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L72-L79] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L113-L129, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L137-L164, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L166-L173, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L137-L160, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L244-L256, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L219-L229, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L265-L267, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L198-L207, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L210-L228, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L121-L125, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L72-L79, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L19-L24, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L163-L167, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L264-L267] feature: "xiaoyi-calendar-tools" entry_points: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py"] source_globs: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py"] @@ -51,3 +51,12 @@ search 中 start_time/end_time 缺失或 _parse_time_string_ymd_hhmmss 抛 Value + + +**依赖同包 .utils 辅助函数与共享 execute_device_command 下发命令** +模块从 .utils 导入 execute_device_command、format_success_response、raise_if_device_error、ToolInputError(L19–L24)。create 将命令委托给 await execute_device_command("CreateCalendarEvent", ...),仅当 result 为 dict 时调用 raise_if_device_error(L163–L167);search 委托 execute_device_command("SearchCalendarEvent", ...) 后无条件调用 raise_if_device_error(L264–L267)。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L19–L24](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py#L19-L24), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L163–L167](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py#L163-L167), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L264–L267](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py#L264-L267) + + + diff --git a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-call-phone-tool.md b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-call-phone-tool.md index 3687d8cc..a323ef64 100644 --- a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-call-phone-tool.md +++ b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-call-phone-tool.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L45-L107, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L24-L44, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L98-L107, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L46-L61, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L70-L82, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L14-L21, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L91-L96, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L171-L207, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L109-L113] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L45-L107, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L24-L44, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L98-L107, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L46-L61, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L70-L82, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L14-L21, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L91-L96, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L171-L207, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L109-L113, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L53-L61, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L91-L98, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L46-L55] feature: "xiaoyi-call-phone-tool" entry_points: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py"] source_globs: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py"] @@ -60,3 +60,12 @@ call_phone 从 .utils 导入 execute_device_command、raise_if_device_error、To + + +**输入校验抛 ToolInputError;其他异常被包装为 RuntimeError 且 ToolInputError 原样重抛** +phone_number 为空/非字符串、strip 后为空或 slot_id 不在 (0,1) 时抛 ToolInputError(其 status 属性为 400;docstring 称框架会返回 HTTP 400,但框架处理代码未在所示片段中);except 分支中 ToolInputError 原样 raise,其余 Exception 记录 error 日志并以 RuntimeError("拨打电话失败: ...") from e 重抛。execute_device_command 的非 dict 输出先兜底为 {} 再经 raise_if_device_error 检查。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L53–L61](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py#L53-L61), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L91–L98](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py#L91-L98), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L109–L113](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py#L109-L113), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L46–L55](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py#L46-L55) + + + diff --git a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-collection-tools.md b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-collection-tools.md index eff82cd6..aeb05586 100644 --- a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-collection-tools.md +++ b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-collection-tools.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L293-L373, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L377-L384, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L165-L231, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L126-L146, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L217-L237, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L293-L303, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L386-L390, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L215-L231] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L293-L373, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L377-L384, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L165-L231, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L126-L146, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L217-L237, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L293-L303, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L386-L390, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L215-L231, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L310-L330, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L19-L24, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L215-L220, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L313-L330] feature: "xiaoyi-collection-tools" entry_points: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py"] source_globs: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py"] @@ -51,3 +51,21 @@ delete_collection/add_collection 中 ToolInputError 被原样 re-raise(如 ite + + +**本地路径上传分支内读取 channels.xiaoyi 三项配置(uri 非空且无远程前缀)** +在 add_collection 中,仅当 uri 为真值且不以 http://、https://、file:// 开头时,才惰性调用 get_config() 读取 channels.xiaoyi 下的 file_upload_url、api_key、uid。缺失 file_upload_url 或 api_key 时抛出 RuntimeError;uid 先经 str() 转换,缺失时变为字符串 "None" 仍为真值,不触发该报错。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L310–L330](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py#L310-L330) + + + + + +**共享 .utils 与模块级导入的 file_upload_helpers、分支内导入的 aiohttp/get_config** +模块顶层从 .utils 导入 execute_device_command、raise_if_device_error、ToolInputError,并从 .file_upload_helpers 导入 XiaoyiObsUploadConfig 和 upload_local_file_public_url(L19–L24);delete_collection 通过 execute_device_command("DeleteCollection", ...) 执行并用 raise_if_device_error 检查(L215–L220)。仅 aiohttp 与 get_config 在本地文件分支内延迟导入(L314–L315),随后用 aiohttp.ClientSession 调用上传助手,返回为空则抛 RuntimeError(L325–L330)。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L19–L24](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py#L19-L24), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L215–L220](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py#L215-L220), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L313–L330](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py#L313-L330) + + + diff --git a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-location-tool.md b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-location-tool.md index b0ba5af1..283ec483 100644 --- a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-location-tool.md +++ b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-location-tool.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py:L33-L86, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py:L34-L68, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L168-L207, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py:L16-L16, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py:L19-L31, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py:L68-L86] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py:L33-L86, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py:L34-L68, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L168-L207, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py:L16-L16, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py:L19-L31, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py:L68-L86, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py:L68-L73, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L215-L228] feature: "xiaoyi-location-tool" entry_points: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py"] source_globs: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py"] @@ -49,3 +49,12 @@ executeParam 各项(achieveType="INTENT"、bundleName="com.huawei.hmos.aidispa + + +**非 dict outputs 先包装;code/retErrCode 校验失败抛 RuntimeError** +L70–L73 将非 dict 的 outputs 包成 {"value": outputs} 后调用 raise_if_device_error。utils.py L215–L228:非 dict 直接 return;顶层 code 未通过 _outputs_top_level_code_ok 时抛 RuntimeError,消息含 errorMsg/errMsg(默认"未知错误")与错误码;retErrCode 仅在非 None 且 str(ret) != "0" 时抛 RuntimeError(空字符串也触发),消息含 retErrCode 值。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py:L68–L73](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py#L68-L73), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L215–L228](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py#L215-L228) + + + diff --git a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-note-tools.md b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-note-tools.md index 9050d8cf..510ea067 100644 --- a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-note-tools.md +++ b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-note-tools.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py:L107-L173, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py:L176-L204, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py:L35-L51, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py:L53-L80, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py:L211-L233, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py:L93-L97, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L210-L228, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L46-L55] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py:L107-L173, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py:L176-L204, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py:L35-L51, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py:L53-L80, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py:L211-L233, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py:L93-L97, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L210-L228, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L46-L55, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py:L15-L23, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py:L82-L87, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L80-L104, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L184-L196] feature: "xiaoyi-note-tools" entry_points: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py"] source_globs: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py"] @@ -49,3 +49,23 @@ create_note(title, content)、search_notes(query)、modify_note(entity_id, text) + + +**create_note 委托 execute_device_command,后者在无 channel 或 last_session_id 为空时抛 RuntimeError** +create_note 通过共享的 execute_device_command("CreateNote", command) 下发命令(note_tools.py:18–23 导入该助手);该助手在 get_runtime_xiaoyi_channel() 返回 None,或 config 中 channels.xiaoyi.last_session_id 为空(含取配置异常后的空串)时抛出 RuntimeError,提示只能在活跃会话中使用。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py:L15–L23](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py#L15-L23), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py:L82–L87](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py#L82-L87), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L80–L104](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py#L80-L104) + + + + + +**共享执行管线用显式 None 检查代替 or 短路:成功空 outputs 保留为 {},但 None 与 {} 返回值相同** +设计推断(非作者历史意图): + +execute_device_command 在 error_result 非空时先抛出,随后用 `{} if result_data is None else result_data` 返回,注释说明空 dict 为假、勿用 or 短路。收益(推断):设备成功但 outputs 为空 dict 时不会被误替换;代价(推断):此处返回的 {} 既可能是真实空结果也可能是 result_data 为 None,调用方无法区分。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L184–L196](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py#L184-L196), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py:L82–L87](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py#L82-L87) + + + diff --git a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-photo-gallery-tools.md b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-photo-gallery-tools.md index c1b3d935..f520efe8 100644 --- a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-photo-gallery-tools.md +++ b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-photo-gallery-tools.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L133-L151, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L192-L195, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L62-L130, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L88-L109, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L208-L229, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L58-L68, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L79-L97, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L111-L116, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L173-L229, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L234-L275, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L154-L156] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L133-L151, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L192-L195, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L62-L130, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L88-L109, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L208-L229, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L58-L68, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L79-L97, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L111-L116, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L173-L229, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L234-L275, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L154-L156, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L189-L199, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L277-L281] feature: "xiaoyi-photo-gallery-tools" entry_points: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py"] source_globs: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py"] @@ -60,3 +60,12 @@ search_photo_gallery 接收单个 query 字符串,非字符串/为空/strip + + +**upload_photo 输入校验失败抛 ToolInputError,其他异常包装为 RuntimeError(本地分支)** +media_uris 为 None、非法 JSON 字符串、解析后非数组或类型不符时,_normalize_media_uris 抛 ToolInputError(含中文信息);规范化后数组为空、超过 5 条或含非非空字符串项时同样抛 ToolInputError。upload_photo 的本地 except 分支将 ToolInputError 原样上抛,其余 Exception 记录日志后包装为 RuntimeError("上传照片失败: …") from e。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L133–L151](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py#L133-L151), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L189–L199](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py#L189-L199), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L277–L281](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py#L277-L281) + + + diff --git a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-pushdata-store-and-viewer.md b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-pushdata-store-and-viewer.md index 89043e93..c3368203 100644 --- a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-pushdata-store-and-viewer.md +++ b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-pushdata-store-and-viewer.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/pushdata_manager.py:L34-L51, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/pushdata_manager.py:L67-L69, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/push_result_tool.py:L136-L152, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/push_result_tool.py:L49-L69, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/push_result_tool.py:L94-L134, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/pushdata_manager.py:L18-L19, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/pushdata_manager.py:L54-L66, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/push_result_tool.py:L49-L51, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/pushdata_manager.py:L56-L66, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/pushdata_manager.py:L49-L51] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/pushdata_manager.py:L34-L51, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/pushdata_manager.py:L67-L69, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/push_result_tool.py:L136-L152, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/push_result_tool.py:L49-L69, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/push_result_tool.py:L94-L134, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/pushdata_manager.py:L18-L19, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/pushdata_manager.py:L54-L66, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/push_result_tool.py:L49-L51, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/pushdata_manager.py:L56-L66, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/pushdata_manager.py:L49-L51, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/push_result_tool.py:L14-L18, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/push_result_tool.py:L49-L62, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/pushdata_manager.py:L112-L141] feature: "xiaoyi-pushdata-store-and-viewer" entry_points: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/push_result_tool.py", "jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/pushdata_manager.py"] source_globs: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/push_result_tool.py", "jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/pushdata_manager.py"] @@ -51,3 +51,12 @@ _read_pushdata_list 捕获 (json.JSONDecodeError, OSError) 记 error 日志并 r + + +**push_result_tool 从同包 pushdata_manager 导入并按 kw 分发到 search/get_all** +push_result_tool.py L18 `from .pushdata_manager import search_push_data, get_all_push_data` 建立同包耦合;view_push_result 内 `results = search_push_data(kw) if kw else get_all_push_data()`(L58)依据剥离空白后的 kw 决定数据源。search_push_data 与 get_all_push_data 均调用 _read_pushdata_list()(L121/L139),读取端共享同一实现。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/push_result_tool.py:L14–L18](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/push_result_tool.py#L14-L18), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/push_result_tool.py:L49–L62](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/push_result_tool.py#L49-L62), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/pushdata_manager.py:L112–L141](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/pushdata_manager.py#L112-L141) + + + diff --git a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-save-to-phone-tools.md b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-save-to-phone-tools.md index 507ab0dc..10787add 100644 --- a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-save-to-phone-tools.md +++ b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-save-to-phone-tools.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py:L29-L40, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/file_upload_helpers.py:L36-L92, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py:L43-L54, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/file_upload_helpers.py:L39-L43, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/file_upload_helpers.py:L60-L89, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py:L35-L40, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/file_upload_helpers.py:L60-L92, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py:L273-L277] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py:L29-L40, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/file_upload_helpers.py:L36-L92, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py:L43-L54, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/file_upload_helpers.py:L39-L43, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/file_upload_helpers.py:L60-L89, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py:L35-L40, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/file_upload_helpers.py:L60-L92, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py:L273-L277, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py:L187-L225, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py:L29-L54, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py:L249-L277, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py:L187-L208, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py:L264-L277, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L46-L55] feature: "xiaoyi-save-to-phone-tools" entry_points: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py"] source_globs: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py", "jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/file_upload_helpers.py"] @@ -51,3 +51,21 @@ _ensure_public_url 对非 http(s) 路径调用 upload_local_file_public_url:PO + + +**save_file_to_file_manager:校验入参后经 _ensure_public_url 换公网 URL 并下发 SaveFileToFileManager 命令** +在 save_file_to_file_manager 内,url/file_name/suffix 任一为空或非字符串时先抛 ToolInputError;随后 _get_obs_config 取配置,_ensure_public_url 对已是 http(s):// 的 url 原样返回,否则经 upload_local_file_public_url 上传,返回空则抛 RuntimeError。命令交给 execute_device_command("SaveFileToFileManager", command),输出非 dict 时包成 {"outputs": outputs},再经 raise_if_device_error 检查,成功后以 content[0].text 返回 json.dumps 的 outputs。注意 L51–L52 中 uid 经 str(xc.get("uid")) 转换,缺失时成为 "None" 字符串并通过非空检查,不触发 ToolInputError。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py:L187–L225](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py#L187-L225), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py:L29–L54](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py#L29-L54), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py:L249–L277](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py#L249-L277) + + + + + +**save_file_to_file_manager 契约:三个字符串必填参数,ToolInputError(status=400) 原样上抛,成功返回 content[0].text 为 JSON 字符串** +调用方须传非空字符串 url、file_name、suffix,任一不满足抛 ToolInputError(L203–L208);该异常在兜底 except 中被原样 re-raise 不包装(L273–L274),其余异常记日志后包装为 RuntimeError 并链上原异常(L275–L277)。ToolInputError 的 __init__ 设 self.status = 400;其 docstring 说明抛出后框架返回 HTTP 400 而非 500,属文档陈述。成功返回 {"content": [{"type": "text", "text": json.dumps(outputs, ensure_ascii=False)}]}。 + +来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py:L187–L208](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py#L187-L208), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py:L264–L277](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py#L264-L277), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L46–L55](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py#L46-L55) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-agent-template-layered-validation.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-agent-template-layered-validation.md index 3c826b95..146874d5 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-agent-template-layered-validation.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-agent-template-layered-validation.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py:L949-L987, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_hot_load_worker.py:L328-L376, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_hot_load_worker.py:L140-L155, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py:L971-L987, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py:L151-L153, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py:L164-L173, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py:L956-L959, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py:L971-L977] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py:L949-L987, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_hot_load_worker.py:L328-L376, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_hot_load_worker.py:L140-L155, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py:L971-L987, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py:L151-L153, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py:L164-L173, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py:L956-L959, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py:L971-L977, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/agent-creator/SKILL.md:L106-L116, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py:L839-L843, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_hot_load_worker.py:L150-L155] feature: "agent-template-layered-validation" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py", "jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_hot_load_worker.py"] @@ -60,3 +60,23 @@ main() 在 quality.errors 或 static.errors 非空时让热加载层 skip(提 + + +**未知 worker status 或环境缺 openjiuwen 时 L2 记为 skip,且 L0/L1 有错则不执行热加载** +worker 返回的 status 不在 ("pass","fail") 时该 Layer 调 skip 记原因与修复建议;worker 进程 ImportError openjiuwen 时返回 status=skip 并附 skip_fix。热加载仅在非 --no-hot-load 且 L0/L1 无 errors 时执行,否则同样 skip。最终 ok 要求三层全部 status=="PASS",故任一 skip 使 main 返回 1。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py:L839–L843](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py#L839-L843), [jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_hot_load_worker.py:L150–L155](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_hot_load_worker.py#L150-L155), [jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py:L971–L987](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py#L971-L987) + + + + + +**SKILL.md 记录的手工校验流程(本轮未执行)** +文档中的人工验收步骤(本轮未执行): + +文档规定 create 与 update 均须运行 `python3 /scripts/validate_template.py `,使用 JiuwenSwarm 运行环境的 python,依次执行 L0/L1/L2,达到 `RESULT: PASS` 才可 register;L2 失败或未执行不能 register;warning(`!`)不阻塞。此为已记录的手工流程,本轮未执行。所供证据未展示针对本校验器的自动化测试。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/agent-creator/SKILL.md:L106–L116](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/agent-creator/SKILL.md#L106-L116) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-arxiv-visual-extraction.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-arxiv-visual-extraction.md index dd63f75b..b170bde0 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-arxiv-visual-extraction.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-arxiv-visual-extraction.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L1410-L1465, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L200-L246, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L55-L56, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L96-L112] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L1410-L1465, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L200-L246, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L55-L56, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L96-L112, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L1370-L1370, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L1298-L1299, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L1224-L1232, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L1330-L1333, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L891-L901, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L1259-L1266] feature: "arxiv-visual-extraction" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py"] @@ -40,3 +40,32 @@ main() 先校验参数,resolve_input 解析输入,本地 PDF 走 copy_local_ + + +**--dpi defaults to DEFAULT_DPI; pages/ rendering only runs when options.keep_pages is true** +L1370 将 --dpi 的 argparse 默认值设为 DEFAULT_DPI。L1298–L1299 显示 render_all_pages(doc, output/"pages", dpi) 仅在 options.keep_pages 为真时执行;未展示禁用时是否创建 pages/ 目录。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L1370–L1370](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py#L1370-L1370), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L1298–L1299](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py#L1298-L1299) + + + + + +**Out-of-range page_index candidates are recorded as failures and skipped; failures are included in manifest** +候选的 page_index 不满足 0 <= page_index < doc.page_count 时,向 failures 追加含 asdict(candidate) 与 error "page_index out of range" 的条目并 continue;manifest 的 "failures" 字段输出这些条目。另外 load_pdffigures_json 在路径缺失时抛 FileNotFoundError,顶层格式不符时抛 ValueError。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L1224–L1232](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py#L1224-L1232), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L1330–L1333](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py#L1330-L1333), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L891–L901](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py#L891-L901) + + + + + +**Caption render fallback via copy2 may duplicate image content; copy failure is uncaught here** +设计推断(非作者历史意图): + +For each candidate the script unions region and caption bboxes and tries render_region; if that raises, or union_rect returns None, it calls shutil.copy2(image_path, caption_path). Benefit (inference): a caption file is still attempted when rendering fails; cost: when copy succeeds the caption file duplicates the plain image instead of including the caption, and copy2 itself is not wrapped in try here so its failure propagates. + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L1259–L1266](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py#L1259-L1266) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ascend-chrome-trace-generator.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ascend-chrome-trace-generator.md index 6e408fb6..23fcba54 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ascend-chrome-trace-generator.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ascend-chrome-trace-generator.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L367-L404, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L372-L379, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L375-L382, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L78-L88, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L384-L387] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L367-L404, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L372-L379, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L375-L382, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L78-L88, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L384-L387, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L15-L15, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L373-L387, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_utils.py:L143-L149, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L19-L19, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L46-L48, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L376-L382, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/reference.md:L371-L382] feature: "ascend-chrome-trace-generator" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py", "jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_save.py", "jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_utils.py", "jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/inspect_rank_pt.py", "jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/bootstrap_trace_toolchain.py", "jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/verify_trace_scaffold.py"] @@ -49,3 +49,34 @@ argparse 默认值:--output 默认 "chrome_trace.json",--clock-divisor 默 + + +**trace_collector 导入 torch 并以 data_dir 中 rank*.pt 文件为输入** +trace_collector.py 导入 torch,CLI 接受包含 rank*.pt 文件的 data_dir 并传给 load_all_ranks;配套 trace_utils.py 用 torch.save 写出 rank{rank_id:03d}.pt,即两侧通过该 torch 序列化文件格式耦合(未显示加载实现细节)。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L15–L15](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py#L15-L15), [jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L373–L387](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py#L373-L387), [jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_utils.py:L143–L149](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_utils.py#L143-L149) + + + + + +**cycle→us 换算用可变模块全局 CLOCK_DIVISOR(默认 50.0,可被 --clock-divisor 覆盖)** +设计推断(非作者历史意图): + +默认 50.0(MHz),main 里通过 global 把 --clock-divisor 赋给 CLOCK_DIVISOR;换算处直接 diff / CLOCK_DIVISOR。收益是适配不同时钟频率;代价(推断)是可变模块全局让换算结果依赖解析 argv 的执行顺序。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L19–L19](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py#L19-L19), [jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L46–L48](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py#L46-L48), [jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L376–L382](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py#L376-L382) + + + + + +**记录的手动流程:运行 trace_collector.py 生成 chrome_trace.json(未执行)** +文档中的人工验收步骤(本轮未执行): + +reference.md 记录了手动命令 `python /scripts/trace_collector.py profiling_data point_map.json -o chrome_trace.json`,读取 rank*.pt 与 point_map.json 并生成 Chrome Trace 格式输出;文档还列出可选参数 --clock-divisor 50.0(时钟 MHz)、--extra-mode seq、--depth 0。此为文档记载的操作与预期结果,明确标注未执行(NOT EXECUTED),不据此断言任何测试已通过。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/reference.md:L371–L382](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/reference.md#L371-L382) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ascend-trace-auto-instrumentation.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ascend-trace-auto-instrumentation.md index f3d34cb0..f50e6028 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ascend-trace-auto-instrumentation.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ascend-trace-auto-instrumentation.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py:L108-L125, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py:L101-L105, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py:L111-L115, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py:L61-L64, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py:L82-L84, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py:L48-L58, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py:L74-L89, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py:L67-L68, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py:L82-L86] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py:L108-L125, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py:L101-L105, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py:L111-L115, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py:L61-L64, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py:L82-L84, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py:L48-L58, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py:L74-L89, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py:L67-L68, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py:L82-L86, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py:L36-L45, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py:L71-L98, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py:L10-L24, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/reference.md:L469-L479] feature: "ascend-trace-auto-instrumentation" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py"] @@ -51,3 +51,32 @@ find_match_brace 扫描到文本末尾仍未配平时返回 len(text)-1(不抛 + + +**apply_file:FUNC_RE 定位函数后按降序插入 B/E 打点并写回** +apply_file 读入文本后由 find_functions 用 FUNC_RE.finditer 提取函数块(find_match_brace 深度配对求 close_brace);无函数返回 0 并报 skip。每个函数体经 should_skip 检查后构造 MoeTracing(TRACE_POINT(label,"B"/"E")) 编辑,编辑按位置降序逐个插入,非 dry_run 时写回磁盘并返回 len(edits)//2。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py:L36–L45](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py#L36-L45), [jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py:L71–L98](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py#L71-L98) + + + + + +**仅标准库模块 + FUNC_RE 多行正则的文本级函数识别** +所引片段中脚本只 import argparse/logging/pathlib/re/dataclass/typing 标准库;函数识别完全依赖 FUNC_RE 单个多行正则(find_functions 于 L38 直接 FUNC_RE.finditer),find_match_brace 为纯字符深度计数,配对失败时回退返回 len(text)-1。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py:L10–L24](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py#L10-L24), [jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py:L36–L45](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py#L36-L45), [jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py:L48–L58](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/instrument_operator.py#L48-L58) + + + + + +**文档化的可选草稿插桩命令(未执行,不能替代人工审查)** +文档中的人工验收步骤(本轮未执行): + +reference.md 记载可运行 `python /scripts/instrument_operator.py --target --root-label processing` 自动写入打点代码,并将其归类为「辅助(可选)——规划/草稿插桩,不能替代人工审查」。这是文档化手动流程,本次未执行,也不证明生成的插桩语义/编译正确。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/reference.md:L469–L479](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/reference.md#L469-L479) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ascend-trace-compile-safety-checker.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ascend-trace-compile-safety-checker.md index 581d9d50..4663b941 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ascend-trace-compile-safety-checker.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ascend-trace-compile-safety-checker.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py:L271-L285, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py:L292-L301, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py:L265-L265, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py:L287-L301, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py:L258-L260, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py:L64-L73, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py:L42-L44, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py:L55-L73, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py:L76-L88, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py:L258-L266, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py:L47-L48, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py:L264-L264, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py:L271-L283] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py:L271-L285, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py:L292-L301, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py:L265-L265, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py:L287-L301, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py:L258-L260, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py:L64-L73, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py:L42-L44, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py:L55-L73, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py:L76-L88, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py:L258-L266, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py:L47-L48, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py:L264-L264, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py:L271-L283, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/reference.md:L483-L484, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/reference.md:L470-L470] feature: "ascend-trace-compile-safety-checker" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/check_compile_safety.py", "jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/run_instrumentation_checks.sh", "jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/validate_trace_points.py"] @@ -69,3 +69,14 @@ check_brace_balance 在剥离注释/字符串后统计深度:depth<0 时 error + + +**Documented manual check: run check_compile_safety.py on ; --strict makes warnings errors (NOT EXECUTED)** +文档中的人工验收步骤(本轮未执行): + +reference.md documents running `python /scripts/check_compile_safety.py ` and that adding `--strict` treats warnings as errors, i.e. the observable expected result is that warnings escalate to errors under --strict; the same table states this check does not replace full OPP/pybind compilation. NOT EXECUTED here. + +来源:[jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/reference.md:L483–L484](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/reference.md#L483-L484), [jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/reference.md:L470–L470](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/reference.md#L470-L470) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ascend-trace-instrumentation-planner.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ascend-trace-instrumentation-planner.md index 109112f8..498832f3 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ascend-trace-instrumentation-planner.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ascend-trace-instrumentation-planner.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L136-L140, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L148-L159, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L27-L27, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L106-L112, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L139-L139, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L148-L149, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L59-L72, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L98-L103, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L108-L118, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L126-L130, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L1-L5, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L7-L18, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L75-L82] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L136-L140, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L148-L159, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L27-L27, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L106-L112, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L139-L139, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L148-L149, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L59-L72, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L98-L103, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L108-L118, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L126-L130, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L1-L5, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L7-L18, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L75-L82, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L39-L56, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L91-L123, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L133-L160, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/reference.md:L469-L477, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L136-L149] feature: "ascend-trace-instrumentation-planner" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py"] @@ -60,3 +60,23 @@ source_globs: ["jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimize + + +**main 从源码提取函数后由 build_plan 做 BFS 展开并写出 JSON 计划** +main 解析必填的 --root/--entry 后,iter_code_files 递归收集 .h/.hpp/.c/.cc/.cpp 文件,extract_functions 用 FUNC_DEF_RE 定位定义、把函数体提取委托给 extract_block(L53)、用 CALL_RE 收集调用名(剔除 KEYWORDS);build_call_graph 之后若入口名不在提取到的函数名集合中则 SystemExit,否则 build_plan 从入口按队列 BFS 展开:已见 (fn, child, depth) 边跳过,超过 MAX_DEPTH 的子节点标 merged=True、merge_reason="depth_limit" 后不再入队,命中 is_low_value_helper(名称不含 HOT_WORDS、以 get/set/check/calc/init 开头且长度 ≤18)的子节点标 helper_merge 后同样不再展开;最终结果连同 root/entry/max_depth 以 indent=2 写入 args.output(默认 instrumentation_plan.json)。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L39–L56](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py#L39-L56), [jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L91–L123](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py#L91-L123), [jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L126–L130](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py#L126-L130), [jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L133–L160](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py#L133-L160) + + + + + +**文档化手动流程:运行 generate_instrumentation_plan.py 产出插桩草案(未执行)** +文档中的人工验收步骤(本轮未执行): + +reference.md L469 将该脚本列为步骤 1–4 的可选辅助("规划/草稿插桩,不能替代人工审查"),L476 给出命令 `python /scripts/generate_instrumentation_plan.py --root --entry `,描述的预期结果是生成打点草案(函数树 + 合并决策)。此为文档记载的手动流程,本回答未执行;所示代码片段中未附带针对 build_plan/extract_functions 的自动化测试。NOT EXECUTED。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/reference.md:L469–L477](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/reference.md#L469-L477), [jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py:L136–L149](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/generate_instrumentation_plan.py#L136-L149) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-audit-integrity-hmac-signing.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-audit-integrity-hmac-signing.md index 1a61b693..95d36cce 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-audit-integrity-hmac-signing.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-audit-integrity-hmac-signing.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L697-L712, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L625-L635, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L654-L663, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L452-L458, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L520-L554, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L175-L180, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L466-L490, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L444-L503, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L537-L560, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L175-L176] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L697-L712, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L625-L635, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L654-L663, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L452-L458, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L520-L554, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L175-L180, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L466-L490, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L444-L503, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L537-L560, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L175-L176, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L466-L468, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L496-L498, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/SKILL.md:L60-L62, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/SKILL.md:L57-L61] feature: "audit-integrity-hmac-signing" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py"] @@ -58,3 +58,25 @@ verify_agent_record 开头两个守卫:integrity 非 dict 或无 signature 返 + + +**按当前脚本哈希验证记录:换取篡改可检测,代价是脚本变更即失效** +设计推断(非作者历史意图): + +验证将记录内 script_hash 与当前运行的 script_hash() 比对,不一致即标记 untrusted_script_hash 并置 invalid(L466–L468),随后 L496–L498 返回 "invalid_agent_audit"。推断(非作者意图):好处是脚本被改动后既有审计记录降级为不可信;成本是正常脚本更新也会使旧记录失效,且所示片段未含恢复路径。SKILL.md L62 本身将该密钥定位为非防篡改安全边界。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L466–L468](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py#L466-L468), [jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L496–L498](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py#L496-L498), [jiuwenswarm/resources/agent/workspace/skills/project-maintainer/SKILL.md:L60–L62](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/project-maintainer/SKILL.md#L60-L62) + + + + + +**文档化的 preflight ensure-key 步骤(未执行)** +文档中的人工验收步骤(本轮未执行): + +SKILL.md L58–L61 记录:在 preflight 运行 `python /scripts/audit_integrity.py ensure-key --repo-root `,默认密钥记录为 `.doc_project_maintainer/project/audit-signing-key.json`(PROJECT_MAINTAINER_AUDIT_SIGNING_KEY);当环境变量缺失时脚本加载该工件密钥并在首次使用时创建,预期结果是后续 audit 命令前密钥已就绪。标注:NOT EXECUTED,本次仅复述文档,未运行。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/project-maintainer/SKILL.md:L57–L61](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/project-maintainer/SKILL.md#L57-L61) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-audit-report-html-renderer.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-audit-report-html-renderer.md index f2b40c7c..bf3e466f 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-audit-report-html-renderer.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-audit-report-html-renderer.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L546-L555, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L42-L53, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L30-L39, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L512-L528] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L546-L555, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L42-L53, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L30-L39, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L512-L528, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/SKILL.md:L198-L210, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L208-L227, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L534-L543, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L42-L50, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L462-L499] feature: "audit-report-html-renderer" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py"] @@ -49,3 +49,34 @@ FileNotFoundError、JSONDecodeError 及顶层非 dict 分别抛出带 label 与 + + +**Integrity refresh subprocess forwarding default flags with repo_root cwd** +The renderer invokes a child process via subprocess.run with cwd=paths["repo_root"], forwarding --scope (value ALL_SCOPE), --report-output, --signing-key-env (argparse default "PROJECT_MAINTAINER_AUDIT_SIGNING_KEY") and --batch-reuse-threshold (default 1); on nonzero returncode it returns a failed integrity state instead of the report. Input maps default under artifact_root/project (coverage-map.json, symbol-audit-map.json) when not overridden. + +来源:[jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L208–L227](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py#L208-L227), [jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L534–L543](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py#L534-L543), [jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L42–L50](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py#L42-L50) + + + + + +**Client-side innerHTML rendering with per-field escapeHtml: interactive at the cost of safety resting on escaping** +设计推断(非作者历史意图): + +Inference: the report's applyFilters/sortBy/renderTable callbacks do all filtering, sorting and table assembly in the browser by concatenating HTML strings into innerHTML. Benefit: search, risk/status filtering and click-to-sort re-render without any server round trip. Cost: every interpolated field (name, kind, source, line, auditStatus, trustResult, riskLevel, suggestedAction) must pass through escapeHtml individually — one missed field is an injection path, and correctness depends on fields outside the shown span. + +来源:[jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L462–L499](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py#L462-L499) + + + + + +**Documented manual procedure: run render_audit_report.py and treat HTML as presentation-only (NOT EXECUTED)** +文档中的人工验收步骤(本轮未执行): + +Documented manual steps, NOT EXECUTED: confirm .doc_project_maintainer/project/coverage-map.json and symbol-audit-map.json exist; run `python /scripts/render_audit_report.py `; the generator refreshes trust classification via audit_integrity.py report unless --skip-integrity-refresh is passed; expected result is project/audit-report.html, a presentation artifact only, with the JSON maps remaining source of truth. If maps are refreshed afterwards, the report reflects older data. + +来源:[jiuwenswarm/resources/agent/workspace/skills/project-maintainer/SKILL.md:L198–L210](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/project-maintainer/SKILL.md#L198-L210) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-cross-channel-history-search-skill.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-cross-channel-history-search-skill.md index e8dc2ee8..af3c710b 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-cross-channel-history-search-skill.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-cross-channel-history-search-skill.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py:L301-L412, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py:L82-L89, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py:L304-L329, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py:L355-L367, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py:L16-L21, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/common/utils.py:L2337-L2338, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py:L142-L152, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py:L187-L189, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py:L381-L397] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py:L301-L412, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py:L82-L89, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py:L304-L329, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py:L355-L367, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py:L16-L21, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/common/utils.py:L2337-L2338, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py:L142-L152, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py:L187-L189, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py:L381-L397, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py:L301-L367, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py:L120-L139, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py:L381-L416, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/SKILL.md:L20-L25, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/SKILL.md:L54-L67] feature: "cross-channel-history-search-skill" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py"] @@ -60,3 +60,23 @@ Benefit: when auto_expand is true and neither --start nor --end was passed, a no + + +**main() argparse CLI: --at/--start/--end window resolution and return 0 on report emission** +main() 通过 argparse 接受 --channel、--session-id、--query(空格分隔关键词)、可重复 --keyword、--start/--end/--at、--window-minutes(默认 120)、--timezone(默认 Asia/Shanghai)、--limit(默认 20)、--max-sessions(默认 200)、--auto-expand/--no-auto-expand。时间窗:有 --start/--end 时缺省端用 now-24h/now;否则 --at 取 center±window_minutes/2;都没有则最近 24 小时;start>end 时交换。窗口计算用 _parse_user_dt,它依次尝试三种 strptime 格式,再尝试 fromisoformat(Z 转 +00:00),无时区则补 tz,全部失败抛 ValueError("无法解析时间: …")。_emit_search_report 之后 return 0(本地返回值,非进程退出码断言)。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py:L301–L367](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py#L301-L367), [jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py:L120–L139](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py#L120-L139), [jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py:L381–L416](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/scripts/search_history.py#L381-L416) + + + + + +**Documented manual procedure: run search_history.py via mcp_exec_command and check SKILL/summary/context markers (NOT EXECUTED)** +文档中的人工验收步骤(本轮未执行): + +SKILL.md 记录的手工流程(未执行):用 mcp_exec_command 运行 `python …/skills/cross-channel-history-retrieval/scripts/search_history.py --channel feishu --query … --start … --end … --limit 30`,预期脚本第一行固定输出 `SKILL=cross-channel-history-retrieval` 以便 grep 确认已执行,并输出 HISTORY_SEARCH_SUMMARY 与 HISTORY_CONTEXT_BLOCK 两个区块;无命中时应说明已检索的时间窗/频道/关键词并询问是否放宽。这只是文档化手工步骤,本次未实际执行,不构成运行验证。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/SKILL.md:L20–L25](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/SKILL.md#L20-L25), [jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/SKILL.md:L54–L67](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/cross-channel-history-retrieval/SKILL.md#L54-L67) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-daily-report-skill.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-daily-report-skill.md index 5c62bea4..2607535d 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-daily-report-skill.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-daily-report-skill.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/generators/report_generator.py:L484-L506, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/collectors/email_collector.py:L99-L110, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/collectors/email_collector.py:L146-L158, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/generators/report_generator.py:L28-L39, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/run_report.py:L745-L762, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/generators/report_generator.py:L23-L25, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/generators/report_generator.py:L80-L92, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/generators/__init__.py:L11-L13, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/generators/report_generator.py:L86-L101, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/SKILL.md:L47-L108] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/generators/report_generator.py:L484-L506, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/collectors/email_collector.py:L99-L110, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/collectors/email_collector.py:L146-L158, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/generators/report_generator.py:L28-L39, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/run_report.py:L745-L762, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/generators/report_generator.py:L23-L25, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/generators/report_generator.py:L80-L92, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/generators/__init__.py:L11-L13, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/generators/report_generator.py:L86-L101, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/SKILL.md:L47-L108, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/generators/report_generator.py:L86-L111] feature: "daily-report-skill" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/generators/__init__.py", "jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/generators/report_generator.py", "jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/run_report.py"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/generators/__init__.py", "jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/generators/report_generator.py", "jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/run_report.py", "jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/analyzers/ai_analyzer.py", "jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/collectors/email_collector.py", "jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/collectors/git_collector.py", "jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/collectors/__init__.py", "jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/collectors/aggregator.py", "jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/report_helper.py", "jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/collectors/todo_collector.py", "jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/analyzers/work_analyzer.py"] @@ -69,3 +69,14 @@ SKILL.md 明确要求用 bash 执行 `python ~/.jiuwenswarm/agent/workspace/skil + + +**AI 分析异常时记录 info 日志并返回 None,代码仍继续调用渲染器** +设计推断(非作者历史意图): + +在 config.enable_ai_analysis 为真时,_run_ai_analysis 捕获 Exception,用 logging.info 记录后返回 None;随后代码仍把 ai_result 传给 _render_daily_report(其内部行为未在所示范围内证明)。收益是单个 Exception 不直接从该分支抛出;代价是失败仅以 info 级日志呈现,且 None 语义需下游解释。此为推断。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/generators/report_generator.py:L86–L111](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/generators/report_generator.py#L86-L111) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-docx-pro-cli.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-docx-pro-cli.md index 97a9d020..99adaf97 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-docx-pro-cli.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-docx-pro-cli.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/docx_pro.py:L404-L421, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/docx_replace.py:L212-L236, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/setup_check.py:L9-L26, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/docx_pro.py:L31-L31, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/docx_pro.py:L174-L179, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/docx_pro.py:L414-L421, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/docx_pro.py:L424-L425] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/docx_pro.py:L404-L421, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/docx_replace.py:L212-L236, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/setup_check.py:L9-L26, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/docx_pro.py:L31-L31, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/docx_pro.py:L174-L179, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/docx_pro.py:L414-L421, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/docx_pro.py:L424-L425, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/docx_pro.py:L141-L171, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/docx_pro.py:L174-L181, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/docx-pro/SKILL.md:L66-L81, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/docx-pro/SKILL.md:L107-L113] feature: "docx-pro-cli" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/docx_pro.py", "jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/setup_check.py"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/docx_pro.py", "jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/setup_check.py", "jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/docx_replace.py", "jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/renderer.py", "jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/md_export.py"] @@ -62,3 +62,23 @@ main 对 args.func(args) 的返回值原样透传,并仅将 FileNotFoundError + + +**replace 的替换对解析契约与 ValueError→退出码 2 的本地返回** +_load_replace_pairs 接受 --map(JSON 对象、[旧,新] 数组或 {find,to} 项)与成对的 -f/-t,两者可叠加;任一来源格式非法、-f/-t 数量不等、无任何替换对或旧文本等于新文本时 raise ValueError,main 捕获后记日志并本地 return 2。cmd_replace 在解析对之后、调用 docx_replace.replace_in_docx 之前,若输出绝对路径等于输入 docx 的绝对路径同样本地 return 2。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/docx_pro.py:L141–L171](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/docx_pro.py#L141-L171), [jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/docx_pro.py:L174–L181](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/docx_pro.py#L174-L181), [jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/docx_pro.py:L404–L421](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/docx-pro/scripts/docx_pro.py#L404-L421) + + + + + +**SKILL.md 记载的 replace 后验查流程(文档化手动程序,未执行)** +文档中的人工验收步骤(本轮未执行): + +SKILL.md 规定:先以 --dry-run 统计各部件命中次数再实跑,之后确认输出路径与输入不同、命中次数符合预期、日志出现“其余 zip 条目字节级一致: True”、段落数/表格数不变且残留计数为 0(新文本包含旧文本时残留>0 属正常)。这是文档化的手动检查步骤,本次 NOT EXECUTED,不构成任何已通过的测试断言。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/docx-pro/SKILL.md:L66–L81](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/docx-pro/SKILL.md#L66-L81), [jiuwenswarm/resources/agent/workspace/skills/docx-pro/SKILL.md:L107–L113](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/docx-pro/SKILL.md#L107-L113) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-financial-document-parser.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-financial-document-parser.md index 200765b2..a4959efe 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-financial-document-parser.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-financial-document-parser.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/financial_parser.py:L82-L103, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/financial_parser.py:L507-L554, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/financial_parser.py:L521-L525, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/financial_parser.py:L421-L425, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/financial_parser.py:L17-L29, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/financial_parser.py:L105-L108, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/financial_parser.py:L135-L158, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/financial_parser.py:L135-L153, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/financial_parser.py:L532-L554, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/financial_parser.py:L135-L148] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/financial_parser.py:L82-L103, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/financial_parser.py:L507-L554, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/financial_parser.py:L521-L525, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/financial_parser.py:L421-L425, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/financial_parser.py:L17-L29, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/financial_parser.py:L105-L108, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/financial_parser.py:L135-L158, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/financial_parser.py:L135-L153, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/financial_parser.py:L532-L554, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/financial_parser.py:L135-L148, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/SKILL.md:L24-L46] feature: "financial-document-parser" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/financial_parser.py"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/financial_parser.py"] @@ -69,3 +69,14 @@ _parse_image 在 HAS_OCR 为 False 时抛 ImportError('需要安装 OCR 依赖: + + +**SKILL.md 记录的 CLI 命令用法(文档化手工流程,未执行)** +文档中的人工验收步骤(本轮未执行): + +SKILL.md 的命令行用法小节给出可直接运行的验证操作:`python financial_parser.py invoice.pdf` 输出 Markdown 报告,`--format json` 输出 JSON,`--format csv` 导出 CSV,`--format all` 输出 Markdown+JSON;并给出 receipt.jpg 图片收据与 statement.csv 银行对账单示例。上述为文档记载的操作与预期输出,本次未执行(NOT EXECUTED)。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/SKILL.md:L24–L46](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/financial-document-parser/SKILL.md#L24-L46) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-huawei-maas-apikey-creation.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-huawei-maas-apikey-creation.md index 4ddb86c3..73e85b20 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-huawei-maas-apikey-creation.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-huawei-maas-apikey-creation.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py:L380-L406, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py:L380-L397, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py:L234-L260, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py:L371-L377, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py:L353-L370, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/lib/huawei_selectors.py:L459-L467, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py:L363-L370] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py:L380-L406, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py:L380-L397, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py:L234-L260, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py:L371-L377, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py:L353-L370, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/lib/huawei_selectors.py:L459-L467, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py:L363-L370, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/SKILL.md:L311-L336] feature: "huawei-maas-apikey-creation" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py", "jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/lib/huawei_selectors.py"] @@ -60,3 +60,14 @@ connect_page 抛异常时 return make_failure("connect_failed", …);goto 失 + + +**Documented manual procedure: serial navigate.py then auto_create_apikey.py with expected success JSON (NOT EXECUTED)** +文档中的人工验收步骤(本轮未执行): + +SKILL.md 记录的手工验证流程:先执行 navigate.py 并等待 stdout 返回 `{"ok": true}` 后再串行执行 auto_create_apikey.py(严禁并行,否则会因加载竞态误报 create_btn_not_found);文档给出的期望成功输出为含 `"ok": true`、`"stage": "apikey"`、`api_key`、`tag`、`description` 的 JSON。此为文档化手工步骤,本次未执行。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/SKILL.md:L311–L336](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/SKILL.md#L311-L336) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-huawei-maas-cdp-authorize.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-huawei-maas-cdp-authorize.md index 4d32950e..a5a28b9b 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-huawei-maas-cdp-authorize.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-huawei-maas-cdp-authorize.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py:L98-L133, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py:L135-L205, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py:L215-L234, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py:L98-L104, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/lib/cdp_client.py:L195-L228, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py:L100-L104, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py:L68-L95, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py:L114-L124, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py:L215-L230, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py:L98-L112, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py:L135-L176, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py:L179-L212, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/lib/flow_state.py:L9-L17] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py:L98-L133, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py:L135-L205, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py:L215-L234, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py:L98-L104, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/lib/cdp_client.py:L195-L228, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py:L100-L104, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py:L68-L95, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py:L114-L124, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py:L215-L230, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py:L98-L112, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py:L135-L176, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py:L179-L212, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/lib/flow_state.py:L9-L17, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/SKILL.md:L285-L309] feature: "huawei-maas-cdp-authorize" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_authorize.py"] @@ -69,3 +69,14 @@ import_playwright 惰性导入 playwright.sync_api,ImportError 时抛 RuntimeE + + +**SKILL.md 记录的手动验证流程(未执行)** +文档中的人工验收步骤(本轮未执行): + +文档化手动流程,未执行:依次运行 navigate.py 与 auto_authorize.py --json --cdp-url ,期望输出形如 {"ok": true, "stage": "authorize", "auth_done": false, "skipped_reason": "no_warning", ...} 或 auth_done=true 且 disclaimer_handled=true;失败降级为提示用户手动完成委托授权后重试。此处仅为文档示例,非已运行断言。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/SKILL.md:L285–L309](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/SKILL.md#L285-L309) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-local-doc-ocr-offline.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-local-doc-ocr-offline.md index 317b57ed..b2b210b3 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-local-doc-ocr-offline.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-local-doc-ocr-offline.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/pdf_to_images.py:L74-L92, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/pdf_to_images.py:L30-L36, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py:L129-L166, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py:L22-L29, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py:L147-L155, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/write_ocr_md.py:L22-L48, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/write_ocr_md.py:L51-L72, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/setup.py:L20-L38] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/pdf_to_images.py:L74-L92, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/pdf_to_images.py:L30-L36, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py:L129-L166, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py:L22-L29, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py:L147-L155, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/write_ocr_md.py:L22-L48, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/write_ocr_md.py:L51-L72, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/setup.py:L20-L38, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/setup.py:L41-L55, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/setup.py:L13-L18, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/SKILL.md:L135-L143] feature: "local-doc-ocr-offline" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py", "jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/write_ocr_md.py", "jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/preprocess_img.py", "jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/pdf_to_images.py", "jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/setup.py"] @@ -60,3 +60,23 @@ _install_one 按 _MIRRORS 顺序尝试:先带 `-i https://pypi.tuna.tsinghua.e + + +**ensure_deps 白名单依赖检测与 all() 短路自动安装** +ocr_offline 的 main 调 _ensure_deps() 但忽略其返回值,随后自行尝试 from rapidocr_onnxruntime import RapidOCR,ImportError 时打印安装提示并以 sys.exit(1) 退出(ocr_offline.py:L147–L155)。_ensure_deps 导入 setup 并返回 setup.ensure_deps(),任何异常仅写 stderr 告警并返回 False(L22–L29)。ensure_deps 用 importlib.util.find_spec 按 PACKAGES(rapidocr_onnxruntime/pymupdf/pillow/numpy)检测缺失;L50 的 all(_install_one(pkg) for pkg in missing) 因生成器短路,某个包安装返回假值后其余缺失包不再尝试安装,此时仅打印手动 pip install 提示并返回 False(setup.py:L41–L55、L13–L18)。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py:L147–L155](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py#L147-L155), [jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py:L22–L29](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py#L22-L29), [jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/setup.py:L41–L55](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/setup.py#L41-L55), [jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/setup.py:L13–L18](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/setup.py#L13-L18) + + + + + +**SKILL.md 记录的两条手动验证命令(未执行)** +文档中的人工验收步骤(本轮未执行): + +SKILL.md「快速验证」给出两条手动命令及预期结果:路线 A 运行 python scripts/ocr_offline.py "测试.pdf" 直接产出 Markdown;路线 B 运行 python scripts/pdf_to_images.py "测试.pdf" -o "./pages" 先渲染,再由多模态 Agent 读取 ./pages/page_01.png 验证。这是文档记载的手动流程,本次未执行;所供证据中未展示针对该功能的自动化断言。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/SKILL.md:L135–L143](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/SKILL.md#L135-L143) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-maas-auto-open-models.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-maas-auto-open-models.md index 44b24bcb..fe525072 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-maas-auto-open-models.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-maas-auto-open-models.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L770-L812, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L772-L810, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L523-L548, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/lib/flow_state.py:L9-L17, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L808-L812, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/SKILL.md:L373-L396] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L770-L812, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L772-L810, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L523-L548, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/lib/flow_state.py:L9-L17, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L808-L812, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/SKILL.md:L373-L396, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L523-L527, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/lib/cdp_client.py:L208-L228, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L49-L57, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L514-L519, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L555-L606, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L686-L705] feature: "maas-auto-open-models" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py"] @@ -60,3 +60,23 @@ connect_page 抛异常返回 make_failure("connect_failed");goto 抛异常或 + + +**依赖 lib.cdp_client.connect_page 与 lib.huawei_selectors 选择器常量** +auto_open_models 在 try 中调用 connect_page(cdp_url, timeout_ms=15_000),任何异常经 make_failure("connect_failed", ...) 本地返回;connect_page 经 pw.chromium.connect_over_cdp 连接后,默认复用 contexts[0] 的已有 page,仅当 context 无 pages 时才新建 page,并 set_default_timeout(timeout_ms)。行定位另依赖 huawei_selectors 导入的 MAAS_DEPLOYMENT_* 常量。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L523–L527](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py#L523-L527), [jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/lib/cdp_client.py:L208–L228](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/lib/cdp_client.py#L208-L228), [jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L49–L57](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py#L49-L57) + + + + + +**批量弹窗减少重复操作的收益与需逐模型复核的代价(成功分支内)** +设计推断(非作者历史意图): + +推断:收益是按 L514–L519 的文档说明,通过一次批量订阅弹窗避免逐模型重复搜索+开通;代价是弹窗关闭≠开通生效,成功分支需关闭弹窗、等待 3 秒、reload 表格并逐个 checked_models 校验"已开通"状态(reload 异常仅记 debug 日志后继续校验),且 L556–L606 循环在首个成功打开弹窗的模型处 break。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L514–L519](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py#L514-L519), [jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L555–L606](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py#L555-L606), [jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L686–L705](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py#L686-L705) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-opc-add-slide.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-opc-add-slide.md index bd5041a5..e9059d3e 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-opc-add-slide.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-opc-add-slide.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py:L167-L186, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py:L20-L48, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py:L108-L122, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py:L177-L182, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py:L133-L163, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py:L7-L9, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py:L104-L130, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py:L167-L173, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py:L13-L18] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py:L167-L186, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py:L20-L48, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py:L108-L122, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py:L177-L182, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py:L133-L163, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py:L7-L9, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py:L104-L130, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py:L167-L173, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py:L13-L18, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py:L167-L171, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py:L84-L90, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py:L104-L112, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py:L154-L156] feature: "opc-add-slide" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py"] @@ -60,3 +60,12 @@ source 以 slideLayout 开头且 layouts/source 不是文件时抛 AddSlideError + + +**仅两个位置参数、无自定义选项的 CLI,编号取自解包目录现状** +_run() 用 argparse 只定义位置参数 unpacked 与 source;所示片段无配置文件或环境变量读取,也未禁用 argparse 默认帮助项。幻灯片号取目录中已有 slideN.xml 的最大值加一(无则 1),sldId 取已有值最大值加一且下限 256;source 以 slideLayout 开头时要求该 layout 文件存在,否则抛 AddSlideError。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py:L167–L171](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py#L167-L171), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py:L84–L90](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py#L84-L90), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py:L104–L112](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py#L104-L112), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py:L154–L156](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/add_slide.py#L154-L156) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-plugin-package-initializer.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-plugin-package-initializer.md index 2b5bb8cf..e234c138 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-plugin-package-initializer.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-plugin-package-initializer.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L184-L202, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L150-L181, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L184-L206, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L129-L131, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L91-L103, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L129-L147, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L158-L162] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L184-L202, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L150-L181, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L184-L206, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L129-L131, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L91-L103, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L129-L147, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L158-L162, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L10-L13, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/SKILL.md:L87-L97, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L196-L202, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L150-L165, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L114-L126] feature: "plugin-package-initializer" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py"] @@ -51,3 +51,32 @@ get_jiuwenswarm_data_dir 读取环境变量 JIUWENSWARM_DATA_DIR 并 strip,非 + + +**仅依赖标准库模块 os/re/sys/pathlib** +所示 import 区只引入 Python 标准库(os、re、sys、pathlib.Path),未显示任何仓库内或第三方导入;因此该脚本在所示范围内不与仓库其他 Python 模块耦合。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L10–L13](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py#L10-L13) + + + + + +**main 仅捕获 ValueError 并返回 1;init_package 内 mkdir 抛出的 OSError 不被捕获** +main() 的 try 仅包裹 resolve_init_target 与 init_package 并只捕获 ValueError,将异常文本经 write_stdout 写出后 return 1。因此名称/路径校验与目录已存在检查(如 L158–L162 的 pkg_dir.exists() 分支、L134–L139 的显式路径父目录约束)都会转为消息加返回值 1;但 init_package 在 L164–L165 调用 mkdir 时抛出的 OSError 不在该 except 子句内,将作为未捕获异常传播,而非返回 1。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L196–L202](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py#L196-L202), [jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L150–L165](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py#L150-L165), [jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L129–L147](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py#L129-L147), [jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L114–L126](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py#L114-L126) + + + + + +**SKILL.md 记录的 mode=create 手工初始化步骤(本轮未执行)** +文档中的人工验收步骤(本轮未执行): + +文档规定仅 mode=create 执行 `python3 /scripts/init_plugin.py `,脚本自行解析落盘路径并输出到 stdout,模板文件带 [TODO] 占位符,且勿手建目录。这是已记录的手工流程,本轮未执行;所示输入未包含任何自动化测试或其断言。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/plugin-creator/SKILL.md:L87–L97](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/plugin-creator/SKILL.md#L87-L97) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ppt-deck-finalize.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ppt-deck-finalize.md index affcf717..7417b090 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ppt-deck-finalize.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ppt-deck-finalize.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py:L117-L137, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py:L100-L109, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py:L192-L197, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py:L139-L146, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py:L56-L66, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py:L132-L137, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py:L44-L49] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py:L117-L137, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py:L100-L109, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py:L192-L197, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py:L139-L146, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py:L56-L66, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py:L132-L137, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py:L44-L49, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/workflows/create-deck.md:L121-L133, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/base/quality-gates.md:L26-L28] feature: "ppt-deck-finalize" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py", "jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/make_blank_template.py", "jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/fill_cover.py", "jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/prune.py", "jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/merge_slides.py"] @@ -69,3 +69,14 @@ FinalizeError 的 docstring 说明在入口外抛 SystemExit 被禁止且使函 + + +**文档化手工流程:finalize_deck.py --cover-title 与收尾门禁(未执行)** +文档中的人工验收步骤(本轮未执行): + +文档记载的手工验证(NOT EXECUTED):运行 `python3 ../scripts/finalize_deck.py output/content.pptx output/final.pptx --cover-title "..." --cover-meta "部门|作者|日期"`,脚本封装 unpack→merge→fill_cover→clean→pack 并在结束时自检,打印页数/母版/版式摘要;若未传 `--cover-title`,收尾的 cover-title 硬门禁判失败(模板 ctrTitle 出厂为空且合并流程不写入)。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/workflows/create-deck.md:L121–L133](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/workflows/create-deck.md#L121-L133), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/base/quality-gates.md:L26–L28](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/base/quality-gates.md#L26-L28) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ppt-evidence-preparation.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ppt-evidence-preparation.md index 073d0dde..df91e07b 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ppt-evidence-preparation.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ppt-evidence-preparation.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py:L294-L316, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py:L95-L102, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py:L52-L53, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py:L322-L356, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py:L243-L253, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py:L134-L141, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py:L256-L260, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py:L346-L349, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py:L68-L70] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py:L294-L316, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py:L95-L102, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py:L52-L53, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py:L322-L356, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py:L243-L253, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py:L134-L141, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py:L256-L260, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py:L346-L349, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py:L68-L70, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py:L324-L353, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/SKILL.md:L150-L168, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py:L231-L253] feature: "ppt-evidence-preparation" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py"] @@ -58,3 +58,25 @@ In main's item loop, any Exception during review/prepare (e.g. copy_asset raisin + + +**Per-item exception capture keeps the loop running but downgrades failures to warnings** +设计推断(非作者历史意图): + +Inference: inside the per-item loop, any Exception (e.g. from use_item/approve_item/prepare_item) sets that item's status to needs-manual with review notes recording the cause, appends an error message, and continues to the next item; the benefit is one failing item does not abort the remaining items, and the cost is that the failure surfaces only as a logged warning plus item-level notes within this loop. + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py:L324–L353](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py#L324-L353) + + + + + +**Documented manual procedure: contact-sheet review then --approve/--used (NOT EXECUTED)** +文档中的人工验收步骤(本轮未执行): + +SKILL.md documents running prepare_evidence.py, then viewing analysis/evidence-contact-sheet.jpg (or the paper-specific contact sheet) before --approve marks an item ready, and --used recording placement into the PPT; statuses are limited to planned/acquiring/ready/used/needs-manual/skipped. This procedure is documented only; it was NOT EXECUTED here. + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/SKILL.md:L150–L168](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/SKILL.md#L150-L168), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py:L231–L253](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py#L231-L253) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ppt-execution-lock-validator.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ppt-execution-lock-validator.md index 37e15d54..cc3eb89b 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ppt-execution-lock-validator.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ppt-execution-lock-validator.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L201-L232, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L234-L247, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L249-L252, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L11-L19, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L11-L14, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L226-L231, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L16-L19, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L8-L9, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L183-L195, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L234-L241] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L201-L232, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L234-L247, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L249-L252, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L11-L19, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L11-L14, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L226-L231, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L16-L19, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L8-L9, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L183-L195, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L234-L241, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L74-L90, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/SKILL.md:L145-L151, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-evidence-plan.js:L106-L133] feature: "ppt-execution-lock-validator" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js", "jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-evidence-plan.js"] @@ -58,3 +58,25 @@ lockArg 为空或 phase 不在 design|generate|deliver 时立即 console.error(U + + +**十二个品牌常量硬编码为字面量,且注释声明需与另外两处文件保持同步** +设计推断(非作者历史意图): + +validate-execution-lock.js 在 L76–L89 将 brand.colors/typography/footer/summary_banner 共十二个键钉死为字面量并逐一 expect()(L90);收益是锁内品牌块被精确校验,代价是 L74–L75 注释所述:换主题需同步修改本文件、base/execution-lock-reference.json 和 scripts/components.js 的 THEME 三处(此同步义务为注释声明,属事实引用;将其判定为设计取舍是本人的推断)。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L74–L90](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js#L74-L90) + + + + + +**SKILL.md 记录的设计阶段双脚本校验流程与失败即禁止生成页面的规则(未执行)** +文档中的人工验收步骤(本轮未执行): + +文档操作(NOT EXECUTED,仅记录于 SKILL.md L145–L149):运行 `node scripts/validate-evidence-plan.js /evidence-plan.json --phase design` 与 `node scripts/validate-execution-lock.js /execution-lock.json --phase design`;文档预期为校验未通过时不得开始页面生成。脚本侧行为(未运行):evidence-plan 校验在参数缺失或 phase 不合法时 exit 2,plan 路径位于 skill 目录内时 exit 1,有错误时 exit 1 否则 exit 0(L106–L133);execution-lock 校验打印汇总行后按 errors 数量 exit 1/0(L249–L252)。所示片段不含针对两校验器的自动化测试。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/SKILL.md:L145–L151](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/SKILL.md#L145-L151), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-evidence-plan.js:L106–L133](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-evidence-plan.js#L106-L133), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L249–L252](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js#L249-L252) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ppt-figure-panel-layout.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ppt-figure-panel-layout.md index 86952b15..57e931ad 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ppt-figure-panel-layout.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ppt-figure-panel-layout.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L1-L7, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L17-L21, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L34-L35, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L82-L101, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L42-L75, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L82-L88, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L26-L37, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L83-L87] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L1-L7, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L17-L21, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L34-L35, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L82-L101, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L42-L75, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L82-L88, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L26-L37, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L83-L87, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L8-L8, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L26-L36, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L10-L21, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L104-L104] feature: "ppt-figure-panel-layout" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js"] @@ -51,3 +51,21 @@ pngSize 先 openSync 再 try/finally closeSync;签名不是 0x89504e47 抛 `no + + +**模块内固定布局常量 WIDE_AR/LABEL_H/GAP 及镜像的标签样式** +布局由三个模块内常量控制:WIDE_AR = 2.5(宽高比达到该值的图独占一行,注释要求介于 1.48 与 2.96 之间)、LABEL_H = 0.22 英寸(每行下方中文标签保留高度)、GAP = 0.12 英寸(行间与并排图间距)。标签字体 Microsoft YaHei 与颜色 595757 从 components.js 镜像复制以避免循环依赖。这些常量随 module.exports 一并导出。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L10–L21](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js#L10-L21), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L104–L104](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js#L104-L104) + + + + + +**依赖 Node fs 同步读取 PNG 头;标签样式常量从 components.js 镜像复制** +pngSize 用 fs.openSync/readSync/closeSync 同步读取文件前 24 字节,从 IHDR 解析宽高;LABEL_FONT/LABEL_COLOR 因 components.js 反向 require 本模块而复制而非导入。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L8–L8](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js#L8-L8), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L17–L21](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js#L17-L21), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L26–L36](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js#L26-L36) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ppt-opc-thumbnail.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ppt-opc-thumbnail.md index 520570fa..eccda255 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ppt-opc-thumbnail.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-ppt-opc-thumbnail.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L52-L55, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L109-L111, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L126-L127, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L58-L63, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L71-L78, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L114-L116, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L135-L140, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L22-L37, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L106-L112, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L135-L144, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L58-L78, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L89-L103, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L40-L45] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L52-L55, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L109-L111, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L126-L127, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L58-L63, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L71-L78, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L114-L116, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L135-L140, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L22-L37, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L106-L112, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L135-L144, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L58-L78, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L89-L103, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L40-L45, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L106-L131, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L66-L86, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/editing.md:L91-L99, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/editing.md:L11-L17] feature: "ppt-opc-thumbnail" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py"] @@ -60,3 +60,23 @@ find_soffice 找不到 soffice 或 mac 路径时抛 ThumbnailError;LibreOffice + + +**_run() 校验 deck 后在临时目录渲染分页并分块写出 JPG(emit 的输出目标未在所示行内)** +`_run()` 先检查 `deck.is_file()`,否则抛 `ThumbnailError`;随后在 `tempfile.TemporaryDirectory()` 中调 `render_pages()`,后者用 `soffice --headless --convert-to pdf`(check=True,timeout=300)转 PDF,确认 PDF 文件存在后导入 fitz,按 `CELL_W/page宽` 缩放栅格化每页为 PIL RGB 图像。回到 `_run()`,页按 `MAX_PER_SHEET=24` 分块,每块经 `build_sheet()` 保存为 `{prefix}{suffix}.jpg`(quality=88,多块时后缀 `-N`),最后调用 `emit()` 报告写入的文件名与页数;`emit` 与 `build_sheet` 的内部实现不在所示范围内。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L106–L131](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py#L106-L131), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L66–L86](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py#L66-L86), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L52–L55](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py#L52-L55) + + + + + +**editing.md 记录的手动调用(未执行):thumbnail.py 生成带页文件名标注的 thumbnails.jpg,默认 3 列** +文档中的人工验收步骤(本轮未执行): + +文档给出 `python scripts/opc/thumbnail.py input.pptx [output_prefix] [--cols N]`,预期产出带页面文件名标注的 `thumbnails.jpg`,默认 3 列;并说明该输出只用于模板版式分析,视觉 QA 需另用 `soffice` + `pdftoppm`。此为文档化手动流程,未在本轮执行;所示源码 span 中无自动化测试,代码 `MAX_PER_SHEET = 24` 与文档所述“每张网格最多 12 页”不一致,应以源码为准并在文档侧修正。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/editing.md:L91–L99](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/editing.md#L91-L99), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/editing.md:L11–L17](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/editing.md#L11-L17), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py:L52–L55](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/thumbnail.py#L52-L55) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-pptx-structural-audit.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-pptx-structural-audit.md index 27ce1c22..e0d9c4eb 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-pptx-structural-audit.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-pptx-structural-audit.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L494-L534, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L506-L509, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L59-L64, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L511-L517, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L295-L308, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L2-L7, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L268-L274, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L11-L20, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L55-L56] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L494-L534, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L506-L509, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L59-L64, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L511-L517, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L295-L308, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L2-L7, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L268-L274, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L11-L20, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L55-L56, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L494-L503, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L528-L534, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L292-L308, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/base/quality-gates.md:L97-L110] feature: "pptx-structural-audit" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py", "jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/qa_density.py", "jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/qa_geometry.py"] @@ -60,3 +60,23 @@ main 捕获 (OSError, ValueError, zipfile.BadZipFile, ET.ParseError),日志输 + + +**main() 以位置参数 pptx 加 --template/--lock/--evidence-plan 选项运行,有 error 时返回 1** +main() 声明位置参数 pptx 与可选 --template、--lock、--evidence-plan(后者启用论文图来源注检查);日志走 stderr。结束时 emit 汇总 error/warning 数与 slides/masters/layouts/font_min_pt,并 `return 1 if report["errors"] else 0`(这是 main 的返回值,非进程退出码的直接证明)。audit() 前置条件:pptx 路径不存在时抛 FileNotFoundError;传入 --lock 时按 UTF-8 JSON 读取锁文件。zip 内缺 [Content_Types].xml、ppt/presentation.xml、ppt/_rels/presentation.xml.rels 任一部件即追加 error。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L494–L503](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py#L494-L503), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L528–L534](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py#L528-L534), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L292–L308](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py#L292-L308) + + + + + +**文档化手动验证:带 --evidence-plan 运行 audit_pptx.py,缺“来源:…”文本时 error 并以退出码 1 结束(NOT EXECUTED)** +文档中的人工验收步骤(本轮未执行): + +quality-gates.md 的“常用命令”给出具体操作:`python scripts/audit_pptx.py output.pptx --template references/template.pptx --lock execution-lock.json --evidence-plan evidence-plan.json --report qa/structure.json`,并记录预期结果:--evidence-plan 打开论文图来源硬校验,按图片字节哈希定位嵌入论文原图的页面,该页若无 addSourceNote 画出的“来源:…”文本则报 error 并以退出码 1 结束。此为文档记载的步骤,本次未执行;提供的输入中无针对该脚本的自动化测试。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/base/quality-gates.md:L97–L110](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/base/quality-gates.md#L97-L110) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-rsi-dataset-folder-check.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-rsi-dataset-folder-check.md index d3090814..fe33493c 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-rsi-dataset-folder-check.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-rsi-dataset-folder-check.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L1-L9, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L67-L73, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L67-L83, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L210-L218, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L99-L127, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L59-L64, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L72-L85, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L210-L214, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L195-L208, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/SKILL.md:L265-L290] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L1-L9, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L67-L73, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L67-L83, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L210-L218, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L99-L127, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L59-L64, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L72-L85, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L210-L214, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L195-L208, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/SKILL.md:L265-L290, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L161-L178] feature: "rsi-dataset-folder-check" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py"] @@ -71,3 +71,12 @@ SKILL.md 记载交付前运行 `python scripts/check_folder.py `, + + +**scorecard 数值与 options.mode 的校验规则(workers/iterations/max_tokens_per_call)** +从 card 读取 workers、iterations(缺省回退 0):iterations < 4*workers 记 problem;options.mode 在 workers>1 时不得为 serial,workers==1 时必须为 serial;max_tokens_per_call(缺省回退 0)低于 32000 记 problem。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L161–L178](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py#L161-L178) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-skill-generator-cli.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-skill-generator-cli.md index 475a3faa..aabe16e2 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-skill-generator-cli.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-skill-generator-cli.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_generator_cli.py:L61-L96, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L444-L455, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_generator_cli.py:L61-L65, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_generator_cli.py:L84-L88, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/url_ingest/web_page.py:L126-L141, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_generator_cli.py:L81-L96, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_generator_cli.py:L47-L58, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/url_ingest/router.py:L31-L41] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_generator_cli.py:L61-L96, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L444-L455, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_generator_cli.py:L61-L65, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_generator_cli.py:L84-L88, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/url_ingest/web_page.py:L126-L141, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_generator_cli.py:L81-L96, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_generator_cli.py:L47-L58, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/url_ingest/router.py:L31-L41, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/reference/operator-playbook.md:L3-L19, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_generator_cli.py:L114-L117, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/url_ingest/router.py:L19-L41, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/url_ingest/web_page.py:L24-L28, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/url_ingest/web_page.py:L14-L15, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/url_ingest/web_page.py:L44-L49, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_generator_cli.py:L40-L44] feature: "skill-generator-cli" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_generator_cli.py"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_generator_cli.py", "jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/url_ingest/web_page.py", "jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/url_ingest/__init__.py", "jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/url_ingest/models.py", "jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/url_ingest/router.py", "jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/url_ingest/wechat_article.py"] @@ -51,3 +51,32 @@ Inference: making AutoFileParser optional (ImportError fallback to plain read) l + + +**url-fetch 可选 --out-json 默认 None;router 仅显式传参才覆盖后端默认** +`url-fetch` 的 `--out-json` 默认 `None`:未提供时走 stdout 日志输出,提供时递归建父目录并写 UTF-8 文件。`fetch_pages_from_url` 的 `timeout`/`user_agent` 默认 `None`,仅当非 None 时才加入转发 kwargs,否则各后端用自身默认(web_page 中为 `DEFAULT_TIMEOUT = 30.0` 与 Chrome/120 `DEFAULT_USER_AGENT`)。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_generator_cli.py:L81–L96](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_generator_cli.py#L81-L96), [jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_generator_cli.py:L114–L117](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_generator_cli.py#L114-L117), [jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/url_ingest/router.py:L19–L41](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/url_ingest/router.py#L19-L41), [jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/url_ingest/web_page.py:L24–L28](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/url_ingest/web_page.py#L24-L28) + + + + + +**web_page 依赖 httpx/bs4,lxml 缺失时回退 html.parser;CLI 把 scripts/ 追加进 sys.path** +`web_page.py` 导入 `httpx` 与 `bs4.BeautifulSoup`;`_parse_html` 先尝试导入 `lxml`,捕获 `ImportError` 后改用内置 `html.parser`。CLI 的 `_ensure_skill_gen_on_path` 把脚本所在目录(追加,非前置)加入 `sys.path`(若尚未存在)。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/url_ingest/web_page.py:L14–L15](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/url_ingest/web_page.py#L14-L15), [jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/url_ingest/web_page.py:L44–L49](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/url_ingest/web_page.py#L44-L49), [jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_generator_cli.py:L40–L44](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_generator_cli.py#L40-L44) + + + + + +**operator-playbook 记录的 CLI 命令示例与预期 stdout 形态(documented_manual,未执行)** +文档中的人工验收步骤(本轮未执行): + +operator-playbook L7–L19 记录以绝对路径运行 skill_generator_cli.py 的 sop-text(--sop-file,可选 --out-text/--print-raw-chars)与 url-fetch(--url,可选 --out-json)命令,并注明 sop-text 无 --out-text 时向 stdout 打印完整 UTF-8 文本、--print-raw-chars 仅打印字符数、url-fetch 输出含 text/title/source_url 的页面对象 JSON 数组。此为已记录的手工操作说明,NOT EXECUTED,本次未运行验证。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/reference/operator-playbook.md:L3–L19](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/reference/operator-playbook.md#L3-L19) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-skill-page-scrape-blocks.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-skill-page-scrape-blocks.md index 4fecd061..a2743d13 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-skill-page-scrape-blocks.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-skill-page-scrape-blocks.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L820-L880, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L820-L876, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L885-L895, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L825-L835, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L718-L757, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L977-L986, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L969-L987, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L753-L757] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L820-L880, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L820-L876, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L885-L895, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L825-L835, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L718-L757, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L977-L986, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L969-L987, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L753-L757, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/SKILL.md:L89-L113] feature: "skill-page-scrape-blocks" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py", "jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/print_blocks.py", "jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/common.py", "jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/download_images.py", "jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/environment_gate.py"] @@ -69,3 +69,14 @@ The browser is launched with --disable-http2 alongside --no-sandbox and related + + +**Documented manual procedure for scrape_page.py to stage01.json (not executed)** +文档中的人工验收步骤(本轮未执行): + +SKILL.md documents a manual invocation `{python} scripts/scrape_page.py ` with expected result `work//stage01.json` containing url, slug, title, blocks (heading/text/image with source field) and video_urls, and that video-platform URLs (Bilibili/YouTube/Vimeo/Xiaohongshu) yield blocks=[] plus video_urls=[url]. This is a documented procedure only — NOT EXECUTED here, and it asserts no automated test coverage over block extraction. + +来源:[jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/SKILL.md:L89–L113](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/SKILL.md#L89-L113) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-sop-structure-extraction.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-sop-structure-extraction.md index a7b4b665..eb4c6bb1 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-sop-structure-extraction.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-sop-structure-extraction.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L14-L15, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_chunk_merge.py:L559-L560, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/__init__.py:L3-L21, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L349-L363, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L289-L306, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L349-L364, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L371-L391] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L14-L15, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_chunk_merge.py:L559-L560, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/__init__.py:L3-L21, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L349-L363, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L289-L306, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L349-L364, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L371-L391, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L19-L23, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_chunk_merge.py:L466-L468, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L343-L369, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_chunk_merge.py:L582-L585, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/reference/sop-structure-pipeline.md:L1-L16, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L394-L403, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L349-L369, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_chunk_merge.py:L563-L585] feature: "sop-structure-extraction" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py", "jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_chunk_merge.py", "jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_fallback.py", "jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/__init__.py", "jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/models.py"] @@ -42,3 +42,41 @@ sop_parser.py 导入 extract_structure_chunked/extract_structure_single_shot 与 + + +**parse_sop_file 为异步入口,调用方必须以关键字传入 invoke_llm_json,返回 (SOPStructure, extraction_meta) 且全文存入 raw_text** +parse_sop_file(file_path, *, invoke_llm_json, parse_options=None) 是 async 函数,invoke_llm_json 为必需的关键字参数,返回 (SOPStructure, extraction_meta);文档字符串声明完整文档文本始终写入 SOPStructure.raw_text。单发路径中若 LLM 抽取后 steps、title、knowledge_items 均为空,则追加 merge_warning "extraction_empty_single_shot" 并抛 ValueError。底层 extract_structure_single_shot 收到的是(可能截断的)原文文本而非完整 prompt,prompt 在其内部由模板构造;invoke_llm_json 带 fallback={} 与 trace_tag="sop_extract_single_shot",若返回非 dict 或为空,helper 本地记录 "empty_llm_response" 并返回空 SOPStructure 与 meta,不在此层抛错。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L394–L403](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py#L394-L403), [jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L349–L369](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py#L349-L369), [jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_chunk_merge.py:L563–L585](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_chunk_merge.py#L563-L585) + + + + + +**默认字符预算常量与 auto 模式:仅当 len(raw_text) > room_single 时走分块路径** +默认值由常量定义:`DEFAULT_SINGLE_SHOT_BUDGET = 12000`、`DEFAULT_MAX_CHUNK_CHARS = 8000`、`DEFAULT_CHUNK_OVERLAP = 1200`、`DEFAULT_MAX_CONTEXT_CHARS = 120_000`、`DEFAULT_SAFETY_MARGIN = 2000`。模式为 `auto`(else 分支)时,仅当 `len(raw_text) > room_single` 才置 `use_chunked` 并调用 `extract_structure_chunked`(非正的 `max_chunk` 以 `None` 传入);分块房间在 `_compute_room_for_chunk` 中仅当 `max_chunk_chars > 0` 且 `room > max_chunk_chars` 时收紧,下限 `max(1, room)`。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L19–L23](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py#L19-L23), [jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L289–L306](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py#L289-L306), [jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_chunk_merge.py:L466–L468](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_chunk_merge.py#L466-L468) + + + + + +**空抽取(无 steps/title/knowledge_items)在单发与分块路径均记入 merge_warnings 并抛 ValueError** +分块路径:若 `not sop.steps and not sop.title and not sop.knowledge_items`,先 append `"extraction_empty_after_chunked"` 到 `merge_warnings` 再 `raise ValueError`;单发路径同样 append `"extraction_empty_single_shot"` 后抛错。单发前若 `len(raw_text) > room_single` 会截断提示词并记 `single_shot_prompt_truncated_to_{room_single}_chars` 警告;更底层地,`extract_structure_single_shot` 在 LLM 返回非 dict 或空 dict 时记 `"empty_llm_response"` 并返回空 `SOPStructure()`(该空结构随后触发上层 ValueError)。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L343–L369](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py#L343-L369), [jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_chunk_merge.py:L582–L585](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_chunk_merge.py#L582-L585) + + + + + +**文档规定的人工验证路径:以 parse_sop_file/parse_sop_raw_text 加 invoke_llm_json 得到 SOPStructure(NOT EXECUTED)** +文档中的人工验收步骤(本轮未执行): + +已有文档 `sop-structure-pipeline.md` 写明唯一受支持路径:调用 `skill_gen.sop_parser.parse_sop_file` 或 `parse_sop_raw_text` 并传入必需的 `invoke_llm_json` callable,即可得到完整 `SOPStructure`;并明确 `skill_generator_cli.py sop-text` 只输出纯文本、不产出 `SOPStructure` JSON(用于排除错误验证方式)。未提供任何针对这些函数的自动化测试断言;本程序为 documented_manual,NOT EXECUTED。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/reference/sop-structure-pipeline.md:L1–L16](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/reference/sop-structure-pipeline.md#L1-L16) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-xlsx-add-computed-column.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-xlsx-add-computed-column.md index bf0c5eb4..3736a444 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-xlsx-add-computed-column.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-xlsx-add-computed-column.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L67-L115, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L57-L78, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py:L50-L77, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L28-L38, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L105-L109, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L21-L25, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L67-L78, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L51-L65, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L111-L116, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L104-L109, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py:L242-L257] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L67-L115, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L57-L78, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py:L50-L77, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L28-L38, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L105-L109, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L21-L25, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L67-L78, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L51-L65, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L111-L116, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L104-L109, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py:L242-L257, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/SKILL.md:L97-L108, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/SKILL.md:L118-L127] feature: "xlsx-add-computed-column" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py"] @@ -69,3 +69,14 @@ resolve_worksheet raises SystemExit("sheet not found: ") when the display + + +**Documented manual edit-and-verify procedure for the add-column flow (NOT EXECUTED)** +文档中的人工验收步骤(本轮未执行): + +SKILL.md documents a manual procedure: unpack input.xlsx with xlsx_unpack.py, run xlsx_add_column.py (e.g. --col G with --formula '=F{row}/$F$10' --formula-rows 2:9 --total-row 10 --total-formula '=SUM(G2:G9)' --numfmt '0.0%' --border-row 10 --border-style medium), repack with xlsx_pack.py into output.xlsx, then verify with `xlsx_reader.py --diff-against input.xlsx` and confirm original sheet names, named ranges, pivots/macros, and a sample of original data are present; if verification fails, fix before delivering. These steps are documented only and were NOT EXECUTED here. + +来源:[jiuwenswarm/resources/agent/workspace/skills/xlsx/SKILL.md:L97–L108](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/SKILL.md#L97-L108), [jiuwenswarm/resources/agent/workspace/skills/xlsx/SKILL.md:L118–L127](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/SKILL.md#L118-L127) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-xlsx-doctor-selfcheck.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-xlsx-doctor-selfcheck.md index 46113dab..09f9a4f6 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-xlsx-doctor-selfcheck.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-xlsx-doctor-selfcheck.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L104-L134, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L8-L11, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L105-L107, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L118-L130, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L133-L134, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L50-L61, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L64-L71, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L74-L93, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L56-L61, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L86-L101, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L115-L116, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L34-L37, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L86-L96] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L104-L134, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L8-L11, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L105-L107, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L118-L130, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L133-L134, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L50-L61, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L64-L71, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L74-L93, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L56-L61, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L86-L101, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L115-L116, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L34-L37, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L86-L96, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L20-L37, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L104-L107, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/SKILL.md:L26-L28, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L8-L12] feature: "xlsx-doctor-selfcheck" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py"] @@ -60,3 +60,23 @@ check_py_deps 通过 importlib.import_module 逐个导入并读取 __version__ + + +**doctor.py 仅显式注册 --json 开关,检查清单由模块常量硬编码** +main() 用 argparse 只显式注册 --json(store_true),必需项清单硬编码在模块常量:PY_DEPS 中 openpyxl、pandas required=True 而 lxml 为 False;CLI_TOOLS 中 soffice(libreoffice)与 pdftoppm(poppler-utils)均 required=True;CJK_FONT_HINTS 十个字体名任一命中即足够。L115–L116 显示仅 required 且 not ok 的项影响整体 ok。argparse 自身还附带默认帮助行为,此处不计入显式注册项。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L20–L37](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py#L20-L37), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L104–L107](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py#L104-L107), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L115–L116](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py#L115-L116) + + + + + +**SKILL.md 记录的自检运行步骤与 doctor.py 文档化的退出码约定(未执行)** +文档中的人工验收步骤(本轮未执行): + +SKILL.md 记录一次性环境自检命令 `python3 SKILL_DIR/scripts/doctor.py`(检查 python、openpyxl、libreoffice、poppler 及 CJK 字体);doctor.py 文档字符串声明用法 `python3 doctor.py [--json]`,退出码 0 表示全部必需检查通过、1 表示有必需项缺失。这是文档化手工流程,本次未执行,不构成已通过的运行时验证。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/xlsx/SKILL.md:L26–L28](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/SKILL.md#L26-L28), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py:L8–L12](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/doctor.py#L8-L12) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-xlsx-formula-check.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-xlsx-formula-check.md index 9d461e0a..96999453 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-xlsx-formula-check.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-xlsx-formula-check.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py:L27-L57, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py:L60-L79, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py:L17-L22, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py:L38-L40, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py:L9-L11, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py:L30-L30, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py:L24-L24, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py:L61-L71, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py:L67-L79, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py:L82-L83] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py:L27-L57, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py:L60-L79, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py:L17-L22, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py:L38-L40, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py:L9-L11, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py:L30-L30, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py:L24-L24, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py:L61-L71, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py:L67-L79, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py:L82-L83, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/SKILL.md:L169-L172, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py:L3-L11] feature: "xlsx-formula-check" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py"] @@ -69,3 +69,14 @@ L17–L22 捕获导入 Exception,向 stderr 打印 "openpyxl is required: ..." + + +**已记录的手动静态校验命令与退出码判定(未执行)** +文档中的人工验收步骤(本轮未执行): + +SKILL.md 记录的手动流程:`formula_check.py file.xlsx --report`,以退出码 0 判定为未发现问题;docstring 约定 0=无错误、1=发现问题、2=用法错误,且 main 中以 `return 0 if ok else 1`(L79)对应。脚本只做静态扫描、不执行公式,需要新鲜缓存值时须先运行 libreoffice_recalc.py。以上步骤在本条目中明确未执行(NOT EXECUTED)。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/xlsx/SKILL.md:L169–L172](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/SKILL.md#L169-L172), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py:L3–L11](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py#L3-L11), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py:L67–L79](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/formula_check.py#L67-L79) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-xlsx-insert-row.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-xlsx-insert-row.md index 293cf655..67caf2f7 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-xlsx-insert-row.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-xlsx-insert-row.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L60-L91, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L3-L20, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L50-L58, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L29-L36, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L53-L60, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L71-L78, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py:L96-L100, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py:L50-L54, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py:L50-L66, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L94-L95, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py:L154-L169, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L14-L20, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/SKILL.md:L97-L108, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/SKILL.md:L128-L144] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L60-L91, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L3-L20, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L50-L58, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L29-L36, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L53-L60, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L71-L78, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py:L96-L100, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py:L50-L54, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py:L50-L66, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L94-L95, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py:L154-L169, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L14-L20, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/SKILL.md:L97-L108, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/SKILL.md:L128-L144, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L25-L26, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L60-L68, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py:L8-L10] feature: "xlsx-insert-row" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py", "jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_shift_rows.py", "jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py"] @@ -71,3 +71,12 @@ SKILL.md documents unpacking, running xlsx_insert_row.py with --at/--text/--valu + + +**xlsx_insert_row 依赖共享模块 _xlsx_common,后者运行时依赖 lxml** +xlsx_insert_row.py 通过 `import _xlsx_common as X` 使用其 first_sheet_name、resolve_worksheet、parse、get_sheetdata、shift_rows、extend_ranges 等助手完成插行;_xlsx_common.py 顶部 `from lxml import etree`,因此该功能运行需要 lxml。所示行未涉及其他脚本的依赖关系。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L25–L26](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py#L25-L26), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L60–L68](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py#L60-L68), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py:L8–L10](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py#L8-L10) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-xlsx-reader-structural-diff.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-xlsx-reader-structural-diff.md index 434080bd..3e8f8e94 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-xlsx-reader-structural-diff.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-xlsx-reader-structural-diff.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L25-L29, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L32-L44, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L165-L178, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L199-L200, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L126-L141, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L67-L71, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L81-L101, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L126-L130, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L156-L196] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L25-L29, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L32-L44, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L165-L178, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L199-L200, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L126-L141, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L67-L71, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L81-L101, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L126-L130, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L156-L196, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/SKILL.md:L97-L108] feature: "xlsx-reader-structural-diff" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py"] @@ -58,3 +58,14 @@ diff_against wraps _sheet_sample calls in try/except: on exception it appends 'c + + +**SKILL.md 规定的保存后 --diff-against 校验流程(未执行)** +文档中的人工验收步骤(本轮未执行): + +SKILL.md L103–L105 规定:保存 output.xlsx 后运行 `xlsx_reader.py --diff-against input.xlsx`,确认原有 sheet 名称、named ranges、透视表/宏及原始数据样本仍在;若校验失败须先修复再交付。这是已记录的手工流程,本文未执行。所提供材料不含该脚本的测试文件。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/xlsx/SKILL.md:L97–L108](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/SKILL.md#L97-L108) + + + diff --git a/knowledge/repos/jiuwenswarm/components/extensions-plugins/feature-depth-agentos-sandbox-create-lifecycle.md b/knowledge/repos/jiuwenswarm/components/extensions-plugins/feature-depth-agentos-sandbox-create-lifecycle.md index 90682276..9d528d2a 100644 --- a/knowledge/repos/jiuwenswarm/components/extensions-plugins/feature-depth-agentos-sandbox-create-lifecycle.md +++ b/knowledge/repos/jiuwenswarm/components/extensions-plugins/feature-depth-agentos-sandbox-create-lifecycle.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/agentos/agentos_router/registry_client.py:L338-L339, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/agentos/agentos_router/registry_client.py:L495-L535, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/agentos/agentos_router/stale_cleanup.py:L22-L53, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/agentos/agentos_router/agent_manager.py:L406-L412, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/agentos/agentos_router/agent_manager.py:L507-L534, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/agentos/agentos_router/stale_cleanup.py:L61-L78, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/extensions/test_agentos_agent_manager.py:L127-L141] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/agentos/agentos_router/registry_client.py:L338-L339, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/agentos/agentos_router/registry_client.py:L495-L535, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/agentos/agentos_router/stale_cleanup.py:L22-L53, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/agentos/agentos_router/agent_manager.py:L406-L412, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/agentos/agentos_router/agent_manager.py:L507-L534, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/agentos/agentos_router/stale_cleanup.py:L61-L78, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/extensions/test_agentos_agent_manager.py:L127-L141, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/agentos/agentos_router/router_client.py:L878-L896, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/agentos/agentos_router/router_client.py:L2243-L2258, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/agentos/agentos_router/agent_manager.py:L414-L436, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/agentos/agentos_router/agent_manager.py:L451-L461, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/agentos/agentos_router/agent_manager.py:L98-L99] feature: "agentos-sandbox-create-lifecycle" entry_points: ["jiuwenswarm/extensions/agentos/agentos_router/router_client.py"] source_globs: ["jiuwenswarm/extensions/agentos/agentos_router/router_client.py", "jiuwenswarm/extensions/agentos/agentos_router/agent_manager.py", "jiuwenswarm/extensions/agentos/agentos_router/config.py", "jiuwenswarm/extensions/agentos/agentos_router/stale_cleanup.py"] @@ -60,3 +60,21 @@ enabled 即 bool(self._base_url)。list_instances 在 not self.enabled 时不发 + + +**Router 连接预热:get_or_create_agent(acquire=True) 后建立 WS 客户端** +router_client 的连接预热回调先查 self._closed 提前返回,再以 BUILTIN_AGENT_TYPE 调用 _agent_manager.get_or_create_agent(user_id, agent_type, creator=self._create_agent, acquire=True),拿到 runtime 后继续执行 await self._get_ws_client(runtime)。envelope 路径 _resolve_agent 则从 envelope 取 user_id,并以 key_values/metadata 携带 session_id 委托同一入口,acquire 由调用方传入(默认 False)。 + +来源:[jiuwenswarm/extensions/agentos/agentos_router/router_client.py:L878–L896](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/agentos/agentos_router/router_client.py#L878-L896), [jiuwenswarm/extensions/agentos/agentos_router/router_client.py:L2243–L2258](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/agentos/agentos_router/router_client.py#L2243-L2258) + + + + + +**get_agent:加锁查询,acquire=True 仅在 runtime.is_ready() 时递增 task_count** +get_agent(user_id, agent_type, *, key_values=None, acquire=False) 在 _runtimes_lock 内查 key,未命中返回 None;仅当 acquire=True 且 runtime.is_ready() 成立才调用 _acquire_locked,随后返回 runtime.snapshot()。调用方须配对 release(key):release 对已消失的 runtime 是空操作,否则把 task_count 减一(不低于 0)并 touch 更新 last_active_at。 + +来源:[jiuwenswarm/extensions/agentos/agentos_router/agent_manager.py:L414–L436](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/agentos/agentos_router/agent_manager.py#L414-L436), [jiuwenswarm/extensions/agentos/agentos_router/agent_manager.py:L451–L461](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/agentos/agentos_router/agent_manager.py#L451-L461), [jiuwenswarm/extensions/agentos/agentos_router/agent_manager.py:L98–L99](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/agentos/agentos_router/agent_manager.py#L98-L99) + + + diff --git a/knowledge/repos/jiuwenswarm/components/extensions-plugins/feature-depth-video-agent-managed-task-service.md b/knowledge/repos/jiuwenswarm/components/extensions-plugins/feature-depth-video-agent-managed-task-service.md index 595124e9..5d9d053a 100644 --- a/knowledge/repos/jiuwenswarm/components/extensions-plugins/feature-depth-video-agent-managed-task-service.md +++ b/knowledge/repos/jiuwenswarm/components/extensions-plugins/feature-depth-video-agent-managed-task-service.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/backend/tasks/service.py:L183-L210, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/backend/tasks/service.py:L491-L533, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/tests/backend/test_managed_tasks.py:L69-L84, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/backend/tasks/service.py:L79-L113, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/backend/task_adapter.py:L283-L293, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/backend/tasks/service.py:L582-L591] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/backend/tasks/service.py:L183-L210, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/backend/tasks/service.py:L491-L533, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/tests/backend/test_managed_tasks.py:L69-L84, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/backend/tasks/service.py:L79-L113, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/backend/task_adapter.py:L283-L293, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/backend/tasks/service.py:L582-L591, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/backend/tasks/service.py:L219-L236, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/backend/tasks/store.py:L36-L48] feature: "video-agent-managed-task-service" entry_points: ["jiuwenswarm/extensions/video_duplex/backend/tasks/service.py"] source_globs: ["jiuwenswarm/extensions/video_duplex/backend/tasks/service.py", "jiuwenswarm/extensions/video_duplex/backend/tasks/rail.py"] @@ -69,3 +69,12 @@ test_retry_conflict_scope_and_cancel_before_dispatch asserts submit with the sam + + +**submit 依赖注入的 store 的 get/put/command;store.transaction 依赖 sqlite3(timeout=10、BEGIN IMMEDIATE)** +submit(回放未命中时)调用注入的 self.store.get 校验 depends_on 依赖、put 持久化任务、command 记录 command_id 回执,随后 kick() 并返回 task。store.transaction 以 sqlite3.connect(path, timeout=10) 开连接,执行 BEGIN IMMEDIATE 后 yield db 并 commit;BaseException 时 rollback 并 re-raise,finally 中关闭连接。所示行不证明 submit 进入 transaction。 + +来源:[jiuwenswarm/extensions/video_duplex/backend/tasks/service.py:L219–L236](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/video_duplex/backend/tasks/service.py#L219-L236), [jiuwenswarm/extensions/video_duplex/backend/tasks/store.py:L36–L48](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/video_duplex/backend/tasks/store.py#L36-L48) + + + diff --git a/knowledge/repos/jiuwenswarm/components/extensions-plugins/feature-depth-yuanrong-agent-file-transfer.md b/knowledge/repos/jiuwenswarm/components/extensions-plugins/feature-depth-yuanrong-agent-file-transfer.md index 2d6d6c39..f73080ab 100644 --- a/knowledge/repos/jiuwenswarm/components/extensions-plugins/feature-depth-yuanrong-agent-file-transfer.md +++ b/knowledge/repos/jiuwenswarm/components/extensions-plugins/feature-depth-yuanrong-agent-file-transfer.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/yuanrong_frontend_client.py:L1304-L1332, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/yuanrong_frontend_client.py:L1315-L1324, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/container_file_http.py:L618-L626, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/yuanrong_frontend_client.py:L1333-L1369, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/extensions/test_yuanrong_frontend_client.py:L1171-L1183, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/yuanrong_frontend_client.py:L924-L967] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/yuanrong_frontend_client.py:L1304-L1332, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/yuanrong_frontend_client.py:L1315-L1324, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/container_file_http.py:L618-L626, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/yuanrong_frontend_client.py:L1333-L1369, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/extensions/test_yuanrong_frontend_client.py:L1171-L1183, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/yuanrong_frontend_client.py:L924-L967, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/yuanrong_frontend_client.py:L936-L948] feature: "yuanrong-agent-file-transfer" entry_points: ["jiuwenswarm/extensions/yuanrong_frontend_client.py"] source_globs: ["jiuwenswarm/extensions/yuanrong_frontend_client.py", "jiuwenswarm/gateway/channel_manager/web/container_file_http.py"] @@ -58,3 +58,14 @@ test_mkdir_agent_dir_rejects_empty_path 断言 path 为空白时抛出 match="pa + + +**mkdir 输入校验用两种异常类型:空值抛 ValueError,路径含 NUL 抛 YuanrongAgentFileError(400)** +设计推断(非作者历史意图): + +在 936-948 行的本地分支中,instance_id 或 path 归一化后为空分别抛 ValueError,而 path 含 "\x00" 抛 YuanrongAgentFileError(http_status=400, error_code="BAD_REQUEST");两种拒绝都发生在第 948 行调用 _normalize_mkdir_mode 之前。(推断)收益是可按异常类型区分编程错误与可透传的请求错误,代价是调用方需同时处理两类异常。 + +来源:[jiuwenswarm/extensions/yuanrong_frontend_client.py:L936–L948](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/yuanrong_frontend_client.py#L936-L948) + + + diff --git a/knowledge/repos/jiuwenswarm/components/extensions-plugins/feature-depth-yuanrong-faas-invocation.md b/knowledge/repos/jiuwenswarm/components/extensions-plugins/feature-depth-yuanrong-faas-invocation.md index a7801174..71b89e57 100644 --- a/knowledge/repos/jiuwenswarm/components/extensions-plugins/feature-depth-yuanrong-faas-invocation.md +++ b/knowledge/repos/jiuwenswarm/components/extensions-plugins/feature-depth-yuanrong-faas-invocation.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/yuanrong_frontend_client.py:L1880-L1908, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/agent_client/extension.py:L31-L60, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/yuanrong_frontend_client.py:L969-L971, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/yuanrong_frontend_client.py:L1936-L1943] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/yuanrong_frontend_client.py:L1880-L1908, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/agent_client/extension.py:L31-L60, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/yuanrong_frontend_client.py:L969-L971, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/yuanrong_frontend_client.py:L1936-L1943, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/yuanrong_frontend_client.py:L1848-L1915, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/agent_client/extension.py:L7-L22, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/agent_client/extension.py:L49-L58, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/yuanrong_frontend_client.py:L1862-L1876, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/yuanrong_frontend_client.py:L1930-L1943, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/extensions/test_yuanrong_frontend_client.py:L166-L196] feature: "yuanrong-faas-invocation" entry_points: ["jiuwenswarm/extensions/yuanrong_frontend_client.py"] source_globs: ["jiuwenswarm/extensions/yuanrong_frontend_client.py", "jiuwenswarm/extensions/clawee.py", "jiuwenswarm/extensions/agent_client/extension.py"] @@ -40,3 +40,41 @@ _ensure_connected 在 self._connected 为假时抛 RuntimeError("client not conn + + +**send_request_stream 经 to_thread 读取器与队列逐项产出 chunk(1848–1915)** +send_request_stream 先 _ensure_connected,用 _build_invoke_payload(envelope, stream=True) 构造载荷,随后 asyncio.create_task(asyncio.to_thread(self._do_invoke_stream, ...)) 启动读取器并循环 await queue.get():"chunk" 项经 _normalize_invoke_chunk 解析后构造 AgentResponseChunk yield,"error" 项 yield 带 {"error": text} 的非完成 chunk,"exception" 项 raise RuntimeError,"done" 项 break 后补发一个 is_complete=True 的收尾 chunk;finally 中 cancel reader_task 并等待其 CancelledError。 + +来源:[jiuwenswarm/extensions/yuanrong_frontend_client.py:L1848–L1915](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/yuanrong_frontend_client.py#L1848-L1915) + + + + + +**agent_client 扩展直接构造 YuanrongFrontendAgentClient 并传入配置参数(7–22, 49–58)** +YuanrongAgentServerClientExtension 在构造时持有传入的 YuanrongFrontendAgentClient 并由 get_client 返回;工厂处以 frontend_endpoint、function_version_urn、agent_namespace 及取自 agent_client 配置的 concurrency(缺省 1)、invoke_timeout_s(缺省 60.0)、agent_timeout_s(缺省 300.0)直接实例化该客户端并包进扩展,形成扩展对该具体客户端类的编译期依赖。 + +来源:[jiuwenswarm/extensions/agent_client/extension.py:L7–L22](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/agent_client/extension.py#L7-L22), [jiuwenswarm/extensions/agent_client/extension.py:L49–L58](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/agent_client/extension.py#L49-L58) + + + + + +**阻塞式 urllib 读取移入工作线程,代价是结果须经队列与线程安全调度回传** +设计推断(非作者历史意图): + +收益(推断):SSE 读取使用阻塞的 urllib.request.urlopen(超时取 self._invoke_timeout_s),通过 asyncio.to_thread 在工作线程执行,使事件循环不必直接阻塞在网络上。成本(推断):结果必须以 (item_type, text) 字符串形式经 asyncio.Queue 中转,例如非 2xx 分支要把错误 JSON 序列化后经 loop.call_soon_threadsafe 投递回循环,增加了序列化与跨线程调度开销。 + +来源:[jiuwenswarm/extensions/yuanrong_frontend_client.py:L1862–L1876](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/yuanrong_frontend_client.py#L1862-L1876), [jiuwenswarm/extensions/yuanrong_frontend_client.py:L1930–L1943](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/yuanrong_frontend_client.py#L1930-L1943) + + + + + +**单测 test_send_request_passes_user_id_in_session_context 以 mock urlopen 验证请求头(166–196)** +该 @pytest.mark.asyncio 测试 patch urllib.request.urlopen 返回 status=200 的 MagicMock,await client.send_request(envelope) 后断言 response.ok 为 True、捕获的 X-session-context JSON 等于 {"sessionCtx": "alice"}、且 TRACE_ID_HEADER 被铸造且不同于 request_id "req-1"。网络层被 mock,仅验证客户端侧 header 构造与响应处理路径;本回复未执行该测试,不声称其通过。 + +来源:[tests/unit_tests/extensions/test_yuanrong_frontend_client.py:L166–L196](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/extensions/test_yuanrong_frontend_client.py#L166-L196) + + + diff --git a/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-channel-security-review-slash-command.md b/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-channel-security-review-slash-command.md index add14dc5..1199553a 100644 --- a/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-channel-security-review-slash-command.md +++ b/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-channel-security-review-slash-command.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/message_handler/prompts/security_review_prompt.py:L243-L255, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/gateway/test_message_handler_security_review_prompt.py:L48-L56, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/gateway/test_message_handler_security_review_prompt.py:L28-L39, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/message_handler/prompts/security_review_prompt.py:L14-L22, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/message_handler/prompts/security_review_prompt.py:L39-L45, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/message_handler/prompts/security_review_prompt.py:L14-L17, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/message_handler/prompts/security_review_prompt.py:L48-L60, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/gateway/test_message_handler_security_review_prompt.py:L136-L141, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/message_handler/prompts/security_review_prompt.py:L10-L11, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/message_handler/prompts/security_review_prompt.py:L63-L72, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/message_handler/prompts/security_review_prompt.py:L5-L7, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/message_handler/message_handler.py:L52-L56] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/message_handler/prompts/security_review_prompt.py:L243-L255, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/gateway/test_message_handler_security_review_prompt.py:L48-L56, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/gateway/test_message_handler_security_review_prompt.py:L28-L39, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/message_handler/prompts/security_review_prompt.py:L14-L22, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/message_handler/prompts/security_review_prompt.py:L39-L45, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/message_handler/prompts/security_review_prompt.py:L14-L17, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/message_handler/prompts/security_review_prompt.py:L48-L60, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/gateway/test_message_handler_security_review_prompt.py:L136-L141, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/message_handler/prompts/security_review_prompt.py:L10-L11, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/message_handler/prompts/security_review_prompt.py:L63-L72, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/message_handler/prompts/security_review_prompt.py:L5-L7, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/message_handler/message_handler.py:L52-L56, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/message_handler/prompts/security_review_prompt.py:L18-L22, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/message_handler/prompts/security_review_prompt.py:L50-L60] feature: "channel-security-review-slash-command" entry_points: ["jiuwenswarm/gateway/message_handler/message_handler.py", "jiuwenswarm/gateway/message_handler/prompts/security_review_prompt.py"] source_globs: ["jiuwenswarm/gateway/message_handler/message_handler.py", "jiuwenswarm/gateway/message_handler/prompts/security_review_prompt.py"] @@ -69,3 +69,12 @@ tests/unit_tests/gateway/test_message_handler_security_review_prompt.py 实际 + + +**_build_inlined_intro 依固定顺序为每个 git 标签追加标题块;fallback 文本指示运行 4 条命令** +在所示片段中,_build_inlined_intro(git_outputs) 先写入固定角色句,然后按 _SECURITY_REVIEW_GIT_COMMANDS 的固定顺序为每个标签(GIT STATUS、FILES MODIFIED、COMMITS、DIFF CONTENT)追加 "LABEL:" 与空行;git_outputs 的输出追加语句未在所示范围内。另有一条 fallback intro 文本,逐条指示运行同样的 4 条 git 命令并审查第 4 步 diff。片段未展示任何命令执行、退出码检查或调用分支。 + +来源:[jiuwenswarm/gateway/message_handler/prompts/security_review_prompt.py:L18–L22](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/message_handler/prompts/security_review_prompt.py#L18-L22), [jiuwenswarm/gateway/message_handler/prompts/security_review_prompt.py:L63–L72](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/message_handler/prompts/security_review_prompt.py#L63-L72), [jiuwenswarm/gateway/message_handler/prompts/security_review_prompt.py:L50–L60](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/message_handler/prompts/security_review_prompt.py#L50-L60) + + + diff --git a/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-gateway-config-hot-reload.md b/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-gateway-config-hot-reload.md index ecdc88ae..a76c8817 100644 --- a/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-gateway-config-hot-reload.md +++ b/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-gateway-config-hot-reload.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L3205-L3254, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L3205-L3242, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L3211-L3241, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L3211-L3242, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L3197-L3216] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L3205-L3254, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L3205-L3242, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L3211-L3241, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L3211-L3242, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L3197-L3216, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/gateway/test_app_gateway_acp.py:L175-L191] feature: "gateway-config-hot-reload" entry_points: ["jiuwenswarm/gateway/app_gateway.py"] source_globs: ["jiuwenswarm/gateway/app_gateway.py"] @@ -60,3 +60,12 @@ revision 不匹配时记 info 日志并 return(放弃重试);set_conf 抛 + + +**helper_unit test: _schedule_gateway_restart sets request event without execv** +In tests/unit_tests/gateway/test_app_gateway_acp.py, the async test test_schedule_gateway_restart_sets_event_without_execv monkeypatches os.execv to record calls, constructs a GatewayRestartRequest, calls _schedule_gateway_restart(restart_request, delay=0.0), then awaits restart_request.ready_event within 1.0s and asserts restart_request.requested is True and execv_calls == []. Coverage is limited to the restart-scheduling helper, not the agent.reload_config retry loop. + +来源:[tests/unit_tests/gateway/test_app_gateway_acp.py:L175–L191](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/gateway/test_app_gateway_acp.py#L175-L191) + + + diff --git a/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-gateway-health-check.md b/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-gateway-health-check.md index b2750e1f..8c127637 100644 --- a/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-gateway-health-check.md +++ b/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-gateway-health-check.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/health_check/health_check.py:L128-L134, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/health_check/health_check.py:L332-L351, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/health_check/health_check.py:L166-L175, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/health_check/health_check.py:L336-L340, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/gateway/test_heartbeat_contracts.py:L45-L64, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/health_check/health_check.py:L142-L150, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/health_check/health_check.py:L177-L216, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/health_check/health_check.py:L76-L92, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/health_check/health_check.py:L9-L18, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/health_check/health_check.py:L200-L207] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/health_check/health_check.py:L128-L134, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/health_check/health_check.py:L332-L351, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/health_check/health_check.py:L166-L175, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/health_check/health_check.py:L336-L340, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/gateway/test_heartbeat_contracts.py:L45-L64, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/health_check/health_check.py:L142-L150, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/health_check/health_check.py:L177-L216, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/health_check/health_check.py:L76-L92, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/health_check/health_check.py:L9-L18, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/health_check/health_check.py:L200-L207, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/health_check/health_check.py:L177-L207, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/health_check/__init__.py:L10-L28] feature: "gateway-health-check" entry_points: ["jiuwenswarm/gateway/health_check/__init__.py", "jiuwenswarm/gateway/health_check/health_check.py"] source_globs: ["jiuwenswarm/gateway/health_check/__init__.py", "jiuwenswarm/gateway/health_check/health_check.py", "jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py"] @@ -69,3 +69,12 @@ test_legacy_health_check_relay_normalizes_at_gateway_ingress 实际调用 Messag + + +**构造注入 AgentServerClient,_tick 内延迟导入 e2a_from_agent_fields 构造信封** +GatewayHealthCheckService 通过构造函数注入 agent_client: "AgentServerClient" 与 config;_tick 局部导入 jiuwenswarm.common.e2a.gateway_normalize.e2a_from_agent_fields 构造 E2A 信封后经 self._agent_client.send_request 发送。包 __init__ 从 health_check 模块再导出 HEALTH_CHECK_CHANNEL_ID、HEALTH_CHECK_OK、HEALTH_CHECK_PROMPT、GatewayHealthCheckService、HealthCheckConfig、IHealthCheck、normalize_active_hours。 + +来源:[jiuwenswarm/gateway/health_check/health_check.py:L128–L134](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/health_check/health_check.py#L128-L134), [jiuwenswarm/gateway/health_check/health_check.py:L177–L207](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/health_check/health_check.py#L177-L207), [jiuwenswarm/gateway/health_check/__init__.py:L10–L28](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/health_check/__init__.py#L10-L28) + + + diff --git a/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-gateway-server-multi-route-ws.md b/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-gateway-server-multi-route-ws.md index 3bbf0db5..b8a1e3d8 100644 --- a/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-gateway-server-multi-route-ws.md +++ b/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-gateway-server-multi-route-ws.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L943-L977, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/gateway/test_app_gateway_acp.py:L656-L668, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L644-L663, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L785-L806, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L900-L925] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L943-L977, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/gateway/test_app_gateway_acp.py:L656-L668, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L644-L663, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L785-L806, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L900-L925, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L656-L663, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/routing/keys.py:L34-L44, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L901-L925, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L1227-L1246] feature: "gateway-server-multi-route-ws" entry_points: ["jiuwenswarm/gateway/app_gateway.py"] source_globs: ["jiuwenswarm/gateway/app_gateway.py", "jiuwenswarm/gateway/channel_manager/channel_manager.py", "jiuwenswarm/gateway/routing/route_binding.py", "jiuwenswarm/gateway/channel_manager/base.py", "jiuwenswarm/gateway/routing/keys.py"] @@ -60,3 +60,21 @@ test_gateway_server_promotes_pending_session_client_after_stale_owner_cleanup + + +**RouteConfig 可选委托字段 ws_channel/session_bind_handler(默认 None)及注释所述的 Channel 委托耦合** +RouteConfig 声明 session_bind_handler 与 ws_channel 两个可选字段,默认均为 None(app_gateway.py:656,662)。随字段注释说明:ws_channel 非 None 时 GatewayServer 仍作 ws 宿主与入站帧解析,但把 ws 与 RoutingKey 委托注册进该外部 Channel 的五维索引(_clients_by_key/_ws_by_id),出站按 delivery.ws_id 由 ChannelManager 派发到该 Channel.send;RoutingKey 即 (user_id, channel_id, app_id, agent_ref, session_id) 五维不可变键。该耦合为注释声明,非本段可执行代码。 + +来源:[jiuwenswarm/gateway/app_gateway.py:L656–L663](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/app_gateway.py#L656-L663), [jiuwenswarm/gateway/routing/keys.py:L34–L44](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/routing/keys.py#L34-L44) + + + + + +**发送帧的受守卫失败返回 False;无路由 session_id 的 msg 走 elif 广播回退否则记 dropped 警告** +_send_frame_to_ws 先用 _ws_is_open(ws 非 None 且 closed 属性为假)守卫,不开放则返回 False;ws.send 抛 ConnectionClosed 时记 info 日志并同样返回 False,不向上抛出(app_gateway.py:901-925)。出站路径中,在一个未展示前置分支的 elif 里,若 _extract_routing_session_id(msg, include_top_level=True) 取不到 session_id 且该 channel 有已注册 clients,则以 gather(..., return_exceptions=True) 广播后 return;否则继续落到 "message dropped: no WebSocket client found" 的 warning 日志(条件取自 msg 而非 frame,后续动作未在摘录中展示)。 + +来源:[jiuwenswarm/gateway/app_gateway.py:L901–L925](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/app_gateway.py#L901-L925), [jiuwenswarm/gateway/app_gateway.py:L1227–L1246](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/app_gateway.py#L1227-L1246) + + + diff --git a/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-im-attachment-persist-hook-969909e1.md b/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-im-attachment-persist-hook-969909e1.md index 4f37e3d4..f956df4b 100644 --- a/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-im-attachment-persist-hook-969909e1.md +++ b/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-im-attachment-persist-hook-969909e1.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/channel/test_attachment_persist.py:L39-L46, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/channel/test_attachment_persist.py:L113-L122, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/channel/test_attachment_persist.py:L40-L46, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/channel/test_attachment_persist.py:L220-L234, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/channel_manager.py:L255-L262, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/channel/test_attachment_persist.py:L93-L109, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/channel/test_attachment_persist.py:L184-L199] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/channel/test_attachment_persist.py:L39-L46, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/channel/test_attachment_persist.py:L113-L122, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/channel/test_attachment_persist.py:L40-L46, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/channel/test_attachment_persist.py:L220-L234, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/channel_manager.py:L255-L262, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/channel/test_attachment_persist.py:L93-L109, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/channel/test_attachment_persist.py:L184-L199, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/channel_manager.py:L255-L264, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/channel_manager.py:L260-L262, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/channel/test_attachment_persist.py:L227-L234, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/channel_manager.py:L177-L180] feature: "im-attachment-persist-hook-969909e1" entry_points: ["jiuwenswarm/gateway/channel_manager/channel_manager.py"] source_globs: ["jiuwenswarm/gateway/channel_manager/channel_manager.py"] @@ -51,3 +51,21 @@ test_persist_hook_failure_raises_attachment_persist_error installs a failing hoo + + +**_persist_hook local branch: labeled call, RuntimeError on not-ok, returns payload, installed via setter** +在 _persist_hook 的可见分支中,以 session_id=None、user_id=None、channel_id=platform 或 "im"、label="im.file_persist" 发起调用;若返回 not ok 则 raise RuntimeError(error 或回退 "im.file_persist failed"),否则返回 payload,最后经 setter(_persist_hook) 安装。调用目标与赋值语句不在片段内,不作断言。 + +来源:[jiuwenswarm/gateway/channel_manager/channel_manager.py:L255–L264](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/channel_manager/channel_manager.py#L255-L264) + + + + + +**not-ok 分支抛 RuntimeError 且错误文案回退到 "im.file_persist failed"** +当调用返回 ok=False 时,_persist_hook 抛出 RuntimeError,消息取 payload.get("error"),取不到则回退为 "im.file_persist failed";该分支在片段内即结束执行(局部 return 不发生)。测试侧另构造带 agent_client=object() 的 manager 并调用 _try_wire_file_persist_hook 后,断言 hook 抛出匹配 "authenticated AgentOS user_id" 的 RuntimeError;该测试的 client 判定条件未在片段内展示。 + +来源:[jiuwenswarm/gateway/channel_manager/channel_manager.py:L260–L262](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/channel_manager/channel_manager.py#L260-L262), [tests/unit_tests/channel/test_attachment_persist.py:L227–L234](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/channel/test_attachment_persist.py#L227-L234), [jiuwenswarm/gateway/channel_manager/channel_manager.py:L177–L180](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/channel_manager/channel_manager.py#L177-L180) + + + diff --git a/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-im-channel-hot-reconfig.md b/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-im-channel-hot-reconfig.md index fecc90be..0f4edd35 100644 --- a/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-im-channel-hot-reconfig.md +++ b/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-im-channel-hot-reconfig.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/channel_manager.py:L362-L364, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L3191-L3196, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L3205-L3242, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L2579-L2586, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L2729-L2745, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L3210-L3212, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L3197-L3203, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L3229-L3239, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/channel_manager.py:L366-L387] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/channel_manager.py:L362-L364, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L3191-L3196, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L3205-L3242, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L2579-L2586, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L2729-L2745, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L3210-L3212, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L3197-L3203, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L3229-L3239, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/channel_manager.py:L366-L387, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L2475-L2517] feature: "im-channel-hot-reconfig" entry_points: ["jiuwenswarm/gateway/app_gateway.py"] source_globs: ["jiuwenswarm/gateway/app_gateway.py", "jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py"] @@ -60,3 +60,12 @@ Benefit (documented in the docstring): retrying one failed optional channel avoi + + +**_stop_channel cancels the channel task, awaits it with a 5s timeout (or in background), stops the channel with a 10s timeout, then unregisters it** +在 app_gateway.py 的 _stop_channel 中:若 task 非空则 task.cancel(),非 background_wait 分支用 asyncio.wait_for(task, timeout=5.0) 等待,TimeoutError/CancelledError/其他异常均只记 warning 或 pass;随后对非空 channel 调 channel.stop()(timeout=10.0,超时或异常仅记日志),最后 channel_manager.unregister_channel(channel.channel_id)。该本地分支不保证停止一定成功——超时后仅记录日志并继续注销。 + +来源:[jiuwenswarm/gateway/app_gateway.py:L2475–L2517](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/app_gateway.py#L2475-L2517) + + + diff --git a/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-im-feishu.md b/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-im-feishu.md index 43d4a986..600a4524 100644 --- a/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-im-feishu.md +++ b/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-depth-im-feishu.md @@ -4,7 +4,7 @@ created: 2026-10-02 updated: 2026-10-02 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/gateway/test_feishu_im_adapter.py:L12-L26, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/im_platforms/feishu/feishu_file_service.py:L203-L207, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/im_platforms/feishu/feishu_file_service.py:L219-L237, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/im_platforms/feishu/feishu_file_service.py:L258-L264, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/im_platforms/feishu/feishu_file_service.py:L273-L273, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/im_platforms/feishu/feishu_connect.py:L3321-L3335, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/im_platforms/feishu/feishu_connect.py:L3341-L3355, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/im_platforms/feishu/feishu_connect.py:L1556-L1595, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/im_platforms/feishu/feishu_connect.py:L1556-L1568, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/base.py:L155-L171, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/im_platforms/feishu/feishu_im_adapter.py:L13-L22, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/im_platforms/feishu/feishu_im_adapter.py:L30-L40] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/gateway/test_feishu_im_adapter.py:L12-L26, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/im_platforms/feishu/feishu_file_service.py:L203-L207, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/im_platforms/feishu/feishu_file_service.py:L219-L237, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/im_platforms/feishu/feishu_file_service.py:L258-L264, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/im_platforms/feishu/feishu_file_service.py:L273-L273, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/im_platforms/feishu/feishu_connect.py:L3321-L3335, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/im_platforms/feishu/feishu_connect.py:L3341-L3355, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/im_platforms/feishu/feishu_connect.py:L1556-L1595, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/im_platforms/feishu/feishu_connect.py:L1556-L1568, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/base.py:L155-L171, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/im_platforms/feishu/feishu_im_adapter.py:L13-L22, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/im_platforms/feishu/feishu_im_adapter.py:L30-L40, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/im_platforms/feishu/feishu_streaming_card.py:L230-L244] feature: "im-feishu" entry_points: ["jiuwenswarm/gateway/channel_manager/im_platforms/feishu/feishu_connect.py"] source_globs: ["jiuwenswarm/gateway/channel_manager/im_platforms/feishu/feishu_connect.py", "jiuwenswarm/gateway/channel_manager/im_platforms/feishu/*"] @@ -67,3 +67,14 @@ send(msg, *, routing_target) 进入时若 self._api_client 为空,记录 warni + + +**流式卡片防抖合并写入的取舍(_flush_after_delay 局部分支)** +设计推断(非作者历史意图): + +推断:L230–L241 的防抖把防抖窗口内的多次文本更新合并为一次 _write_snapshot 调用,收益是减少快照写次数;代价是仅当 self.is_active 为真时才写入,且若写入期间文本继续变化需再次调度延迟刷新,快照可能滞后于最新文本。写入是否送达平台取决于 L244 之后未展示的逻辑,此处不保证。 + +来源:[jiuwenswarm/gateway/channel_manager/im_platforms/feishu/feishu_streaming_card.py:L230–L244](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/channel_manager/im_platforms/feishu/feishu_streaming_card.py#L230-L244) + + + diff --git a/knowledge/repos/jiuwenswarm/components/ide-clients/feature-depth-ide-file-edit-diff-apply.md b/knowledge/repos/jiuwenswarm/components/ide-clients/feature-depth-ide-file-edit-diff-apply.md index d4ee7715..f13231cb 100644 --- a/knowledge/repos/jiuwenswarm/components/ide-clients/feature-depth-ide-file-edit-diff-apply.md +++ b/knowledge/repos/jiuwenswarm/components/ide-clients/feature-depth-ide-file-edit-diff-apply.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L81-L83, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/editor/DiffApplier.kt:L70-L78, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L112-L119, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/editor/DiffApplier.kt:L309-L310, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L70-L85, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L112-L123, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L273-L286, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L75-L79] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L81-L83, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/editor/DiffApplier.kt:L70-L78, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L112-L119, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/editor/DiffApplier.kt:L309-L310, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L70-L85, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L112-L123, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L273-L286, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L75-L79, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L70-L82, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L85-L102, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L70-L79, "openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:docs/zh/ide/vscode/VSCode插件指南.md:L307-L320"] feature: "ide-file-edit-diff-apply" entry_points: ["jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/ui/ChatToolWindow.kt", "jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts"] source_globs: ["jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/ui/ChatToolWindow.kt", "jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts", "jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/editor/DiffApplier.kt", "jiuwenswarm/channels/ide/packages/vscode-extension/src/ui/ChatPanel.ts"] @@ -49,3 +49,34 @@ parseArguments 对非对象且非字符串的 arguments 或 JSON.parse 抛错返 + + +**handleToolCall:异步入口,按 tool_name 过滤并在参数可解析时委托各工具分支** +handleToolCall(event) 是 async、返回 Promise;payload 缺 tool_name 或不在 EDIT_TOOLS 时返回 false,parseArguments 失败时 console.warn 并返回 false。str_replace_editor 的 'str_replace' 分支要求 args.path 存在且 old_str 已定义(new_str 缺省为 ''),然后委托 applyStrReplace(filePath, oldStr, newStr, requireApproval);'create' 委托 writeEntireFile。 + +来源:[jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L70–L82](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts#L70-L82), [jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L85–L102](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts#L85-L102) + + + + + +**守卫不满足时静默返回 false:控制流简单但无用户提示** +设计推断(非作者历史意图): + +(推断)入口对缺失或未列入 EDIT_TOOLS 的 tool_name 直接返回 false、不做提示,仅参数解析失败才 console.warn;这换来简单的调用方布尔语义,代价是守卫分支对用户不可见。 + +来源:[jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L70–L79](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts#L70-L79) + + + + + +**文档化的手动验证:approveEdits 批准/拒绝提示(未执行)** +文档中的人工验收步骤(本轮未执行): + +文档写明:智能体调用 str_replace_editor / write_file / create_file 时扩展应用编辑并弹通知 toast;启用设置 jiuwenswarm.approveEdits 后每次变更前出现批准/拒绝提示,拒绝丢弃编辑、批准写入磁盘。此为文档步骤,标注 NOT EXECUTED,所示输入无自动化测试。 + +来源:[docs/zh/ide/vscode/VSCode插件指南.md:L307–L320](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/docs/zh/ide/vscode/VSCode%E6%8F%92%E4%BB%B6%E6%8C%87%E5%8D%97.md#L307-L320) + + + diff --git a/knowledge/repos/jiuwenswarm/components/ide-clients/feature-depth-ide-turn-rewind-snapshot.md b/knowledge/repos/jiuwenswarm/components/ide-clients/feature-depth-ide-turn-rewind-snapshot.md index 67355b0e..da176551 100644 --- a/knowledge/repos/jiuwenswarm/components/ide-clients/feature-depth-ide-turn-rewind-snapshot.md +++ b/knowledge/repos/jiuwenswarm/components/ide-clients/feature-depth-ide-turn-rewind-snapshot.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L32-L48, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L53-L64, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/settings/JiuwenSwarmSettings.kt:L36-L39, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/settings/JiuwenSwarmSettings.kt:L123-L125, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L55-L63, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L249-L255, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/ui/ChatPanel.ts:L929-L940, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L245-L257, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/ui/ChatPanel.ts:L929-L934, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L22-L24, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L41-L53] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L32-L48, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L53-L64, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/settings/JiuwenSwarmSettings.kt:L36-L39, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/settings/JiuwenSwarmSettings.kt:L123-L125, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L55-L63, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L249-L255, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/ui/ChatPanel.ts:L929-L940, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L245-L257, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/ui/ChatPanel.ts:L929-L934, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L22-L24, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L41-L53, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L245-L259, "openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:docs/zh/ide/vscode/VSCode插件指南.md:L332-L362"] feature: "ide-turn-rewind-snapshot" entry_points: ["jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/ui/ChatToolWindow.kt", "jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts"] source_globs: ["jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/ui/ChatToolWindow.kt", "jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts", "jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/settings/JiuwenSwarmSettings.kt"] @@ -60,3 +60,23 @@ ensureSnapshot 的 catch 分支将 currentTurnSnapshots.set(filePath, null);pe + + +**快照整份读入内存:省去外部存储,但 null 语义有歧义** +ensureSnapshot 将文件全文以 utf-8 字符串读入内存 Map(L57),未落盘外部存储,实现简单;代价是 originalContent === null 同时表示文件原不存在(L59)与读取失败(L61-62)两种情况,performRewind 对 null 一律走删除分支(L251-255),读取失败时可能删除本已存在的文件。 + +来源:[jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L53–L64](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts#L53-L64), [jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L245–L259](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts#L245-L259) + + + + + +**文档化的手工回退步骤(未执行)** +文档中的人工验收步骤(本轮未执行): + +VSCode 插件指南记载:轮次编辑文件后消息列表下方出现回退栏,点击 "⟲ 撤销更改" 后扩展恢复每个被快照的文件、该轮前不存在的文件被删除,并以状态行 "⟲ 已回退 3 个文件" 确认;此为文档化手工流程,NOT EXECUTED,所示证据不含自动化测试。 + +来源:[docs/zh/ide/vscode/VSCode插件指南.md:L332–L362](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/docs/zh/ide/vscode/VSCode%E6%8F%92%E4%BB%B6%E6%8C%87%E5%8D%97.md#L332-L362) + + + diff --git a/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-chat-session-stats-dashboard.md b/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-chat-session-stats-dashboard.md index 02ae3982..fdfc864d 100644 --- a/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-chat-session-stats-dashboard.md +++ b/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-chat-session-stats-dashboard.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/shared-webview/chat.html:L3398-L3407, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/shared-webview/chat.html:L3391-L3396, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/shared-webview/chat.html:L4348-L4361, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/shared-webview/chat.html:L4352-L4364] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/shared-webview/chat.html:L3398-L3407, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/shared-webview/chat.html:L3391-L3396, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/shared-webview/chat.html:L4348-L4361, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/shared-webview/chat.html:L4352-L4364, "openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:docs/zh/ide/jetbrains/JetBrains插件指南.md:L139-L155", openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/shared-webview/chat.html:L4503-L4516] feature: "chat-session-stats-dashboard" entry_points: ["jiuwenswarm/channels/ide/packages/shared-webview/chat.html"] source_globs: ["jiuwenswarm/channels/ide/packages/shared-webview/chat.html"] @@ -58,3 +58,23 @@ When state.contextUsagePercent is null and not (state.contextTokensUsed > 0 and + + +**6% 最小柱高保证零值轮可见但牺牲严格比例** +bars() 对每柱高度取 Math.max(6, Math.round(v / maxVal * 100)),且归一化分母 maxTok/maxDur 由 Math.max(...,1) 保证至少为 1;收益是数值为 0 或极小的轮次仍有 6% 高度可见,代价是低于 6% 的柱不再与数值严格成比例。 + +来源:[jiuwenswarm/channels/ide/packages/shared-webview/chat.html:L4503–L4516](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/shared-webview/chat.html#L4503-L4516) + + + + + +**Documented manual check (NOT EXECUTED): stats bar appears after first turn; chart toggle and hover details after two turns** +文档中的人工验收步骤(本轮未执行): + +JetBrains 插件指南记载(未执行):统计栏在第一轮完成后出现并显示轮数/错误/Token 等指标;两轮或更多后条形图图标切换迷你图,悬停条形可查看该轮详情。此为文档记载的手工核对步骤,非自动化断言。 + +来源:[docs/zh/ide/jetbrains/JetBrains插件指南.md:L139–L155](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/docs/zh/ide/jetbrains/JetBrains%E6%8F%92%E4%BB%B6%E6%8C%87%E5%8D%97.md#L139-L155) + + + diff --git a/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-code-mode-branch-selector.md b/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-code-mode-branch-selector.md index 82492d01..701e3c21 100644 --- a/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-code-mode-branch-selector.md +++ b/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-code-mode-branch-selector.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeBranchSelector.tsx:L36-L36, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeBranchSelector.tsx:L195-L204, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeEnvironmentPanel.tsx:L4-L6, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeEnvironmentPanel.tsx:L47-L49, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeBranchSelector.tsx:L48-L48, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeBranchSelector.tsx:L80-L82, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeBranchSelector.tsx:L192-L207, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeBranchSelector.tsx:L36-L37, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeBranchSelector.tsx:L84-L97] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeBranchSelector.tsx:L36-L36, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeBranchSelector.tsx:L195-L204, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeEnvironmentPanel.tsx:L4-L6, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeEnvironmentPanel.tsx:L47-L49, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeBranchSelector.tsx:L48-L48, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeBranchSelector.tsx:L80-L82, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeBranchSelector.tsx:L192-L207, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeBranchSelector.tsx:L36-L37, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeBranchSelector.tsx:L84-L97, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeBranchSelector.tsx:L262-L270, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeBranchSelector.tsx:L277-L285] feature: "code-mode-branch-selector" entry_points: ["jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeBranchSelector.tsx"] source_globs: ["jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeBranchSelector.tsx", "jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeEnvironmentPanel.tsx"] @@ -60,3 +60,12 @@ CodeEnvironmentPanel 从 './CodeBranchSelector' 导入并在分支行渲染它 + + +**错误以可关闭的 alert 呈现;空仓库(isUnbornHead)时禁用创建分支按钮** +当 error 非空时,菜单内渲染 role='alert' 的错误块(含文案与关闭按钮,点击将 error 置为 null);当 isUnbornHead 为真时,创建分支按钮因 branchWritesBlocked || isUnbornHead 被禁用,并显示提示“空仓库需要完成首次提交后才能创建其他分支”。 + +来源:[jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeBranchSelector.tsx:L262–L270](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeBranchSelector.tsx#L262-L270), [jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeBranchSelector.tsx:L277–L285](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeBranchSelector.tsx#L277-L285) + + + diff --git a/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-code-mode-commit-push.md b/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-code-mode-commit-push.md index 74b8c2bf..bf53b62f 100644 --- a/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-code-mode-commit-push.md +++ b/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-code-mode-commit-push.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeCommitPushControl.tsx:L95-L108, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/gitPublishState.ts:L5-L13, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeCommitPushControl.tsx:L117-L119, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeCommitPushControl.tsx:L133-L151, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeCommitPushControl.tsx:L10-L18, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeCommitPushControl.tsx:L1-L8, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeCommitPushControl.tsx:L133-L148, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeCommitPushControl.tsx:L139-L150, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/gitPublishState.ts:L29-L34] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeCommitPushControl.tsx:L95-L108, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/gitPublishState.ts:L5-L13, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeCommitPushControl.tsx:L117-L119, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeCommitPushControl.tsx:L133-L151, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeCommitPushControl.tsx:L10-L18, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeCommitPushControl.tsx:L1-L8, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeCommitPushControl.tsx:L133-L148, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeCommitPushControl.tsx:L139-L150, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/gitPublishState.ts:L29-L34, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeCommitPushControl.tsx:L245-L250, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeCommitPushControl.tsx:L413-L421] feature: "code-mode-commit-push" entry_points: ["jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeCommitPushControl.tsx"] source_globs: ["jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeCommitPushControl.tsx"] @@ -58,3 +58,14 @@ message 为空白时用 defaultCommitMessage(filesChanged):≤0 为 'Update pr + + +**关闭与取消按钮在 submitting 或 creatingBranch 期间被禁用(仅限这两个按钮)** +设计推断(非作者历史意图): + +对话框头部关闭按钮(L247)和底部取消按钮(L414)的 disabled 守卫均为 submitting || creatingBranch,即等待期间这两条 UI 关闭路径被阻塞;推断这是以牺牲等待期的可取消性换取避免在提交/建分支中途关闭对话框。该证据不覆盖 Escape 或遮罩点击等其他关闭路径,也不证明两标志在 awaited 调用结束后必被复位。 + +来源:[jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeCommitPushControl.tsx:L245–L250](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeCommitPushControl.tsx#L245-L250), [jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeCommitPushControl.tsx:L413–L421](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/features/code-mode/CodeCommitPushControl.tsx#L413-L421) + + + diff --git a/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-context-usage-indicator.md b/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-context-usage-indicator.md index 77c80b31..bdd35fec 100644 --- a/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-context-usage-indicator.md +++ b/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-context-usage-indicator.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx:L62-L78, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx:L142-L158, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx:L64-L78, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx:L142-L148, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/server/runtime/agent_adapter/interface_deep.py:L18674-L18701, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx:L233-L238, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/server/runtime/agent_adapter/interface.py:L5084-L5096] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx:L62-L78, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx:L142-L158, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx:L64-L78, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx:L142-L148, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/server/runtime/agent_adapter/interface_deep.py:L18674-L18701, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx:L233-L238, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/server/runtime/agent_adapter/interface.py:L5084-L5096, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/server/utils/stream_utils.py:L128-L140, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/tests/contextUsageDom.test.mjs:L1-L17, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/tests/contextUsageDom.test.mjs:L32-L80, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/tests/contextUsageDom.test.mjs:L139-L195] feature: "context-usage-indicator" entry_points: ["jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.css", "jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx"] source_globs: ["jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.css", "jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx", "jiuwenswarm/server/runtime/agent_adapter/interface_deep.py", "jiuwenswarm/server/utils/stream_utils.py"] @@ -49,3 +49,23 @@ get_context_usage_event 的 try 块包裹 build_snapshot,except Exception 时 + + +**服务端回填旧版 Core 载荷以保持前端协议版本容错** +设计推断(非作者历史意图): + +stream_utils 在 usage_payload 顶层缺少 session_kv_cache_hit_rate 时,若嵌套 kv_cache.session 是 dict 则回填其 weighted_hit_rate,注释明示目的是让前端协议版本容错;收益是旧载荷仍可展示,代价是服务端需维护兼容分支。此为推断标注:收益/代价由注释与实现推断。 + +来源:[jiuwenswarm/server/utils/stream_utils.py:L128–L140](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/server/utils/stream_utils.py#L128-L140) + + + + + +**contextUsageDom.test.mjs 挂载真实组件并断言 tooltip/明细 DOM 更新** +测试 contextUsageDom.test.mjs 通过 receiveContextUsage 注入快照后,断言 trigger aria-label 含 50%、tooltip 文案含 50%/88.3% 且不含其他来源数值、明细含 4 个类别与 4 个分段、后续快照更新 metric 为 120% 与分段宽度 12.3%,并验证 Escape 关闭且焦点还原、关闭按钮与外点 pointerdown 关闭。这是已有的自动化运行时测试,此处仅描述未执行。 + +来源:[jiuwenswarm/channels/web/frontend/tests/contextUsageDom.test.mjs:L1–L17](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/tests/contextUsageDom.test.mjs#L1-L17), [jiuwenswarm/channels/web/frontend/tests/contextUsageDom.test.mjs:L32–L80](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/tests/contextUsageDom.test.mjs#L32-L80), [jiuwenswarm/channels/web/frontend/tests/contextUsageDom.test.mjs:L139–L195](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/tests/contextUsageDom.test.mjs#L139-L195) + + + diff --git a/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-dev-ws-traffic-logger.md b/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-dev-ws-traffic-logger.md new file mode 100644 index 00000000..7ee4e20f --- /dev/null +++ b/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-dev-ws-traffic-logger.md @@ -0,0 +1,62 @@ +--- +title: "Vite Dev WS Traffic Logger (/__dev/ws-log):实现深读" +created: 2026-10-07 +updated: 2026-10-07 +type: architecture +tags: [jiuwenswarm] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/vite.config.ts:L409-L441, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/vite.config.ts:L355-L367, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/vite.config.ts:L157-L181, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/vite.config.ts:L368-L382, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/vite.config.ts:L429-L436, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/vite.config.ts:L36-L53, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/vite.config.ts:L89-L142, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/vite.config.ts:L423-L440, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/vite.config.ts:L383-L398] +feature: "dev-ws-traffic-logger" +entry_points: ["jiuwenswarm/channels/web/frontend/vite.config.ts"] +source_globs: ["jiuwenswarm/channels/web/frontend/vite.config.ts", "jiuwenswarm/channels/web/frontend/src/components/LogsPanel/index.tsx", "jiuwenswarm/channels/web/app_web.py"] +--- + +# Vite Dev WS Traffic Logger (/__dev/ws-log):实现深读 + +[功能概览](feature-dev-ws-traffic-logger.md) · [owner 入口](_index.md) + + +**POST 回调累积请求体、脱敏后以 JSONL 追加写入日志** +POST 分支用 req.on('data') 累积 raw,end 回调尝试 JSON.parse(失败保留原文),经 maskSensitive 脱敏后写成 `{ts,payload}` 行 append 到 ws-dev.log,成功返回 200 {ok:true}。 + +来源:[jiuwenswarm/channels/web/frontend/vite.config.ts:L409–L441](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/vite.config.ts#L409-L441) + + + + + +**limit 查询参数默认 300,非有限回退 300,有效值夹在 1–2000** +日志路径固定由 resolveProjectRootDir() 推导为 agent/.logs/ws-dev.log;configureServer 时 mkdirSync 递归建目录并 writeFileSync 清空文件。GET 的 limit 缺省 '300',Number.isFinite 不满足时取 300,否则 clamp 到 1–2000。 + +来源:[jiuwenswarm/channels/web/frontend/vite.config.ts:L355–L367](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/vite.config.ts#L355-L367), [jiuwenswarm/channels/web/frontend/vite.config.ts:L157–L181](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/vite.config.ts#L157-L181) + + + + + +**POST 写盘前调用本地 maskSensitive,敏感键值整体掩码但空值/已脱敏/哈希异常有例外** +POST 'end' 回调调用同文件的 maskSensitive(L427),后者递归处理对象/数组,键名命中 looksSecretKey 时将值经 maskWithFp 替换为 ******(fp:..),字符串值再经 maskValueShapes 兜底;maskWithFp 内部空值返回 '******'、已脱敏值原样返回、createHash 异常返回 '******'。中间件本身依赖 fs(mkdirSync/writeFileSync/readFile/appendFile)与 path 解析 agent/.logs/ws-dev.log。与后端 SensitiveDataFilter 一致仅为注释声明。 + +来源:[jiuwenswarm/channels/web/frontend/vite.config.ts:L36–L53](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/vite.config.ts#L36-L53), [jiuwenswarm/channels/web/frontend/vite.config.ts:L89–L142](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/vite.config.ts#L89-L142), [jiuwenswarm/channels/web/frontend/vite.config.ts:L423–L440](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/vite.config.ts#L423-L440) + + + + + +**读错误 ENOENT 返回 200 空列表,其余 500;写失败 500** +GET fs.readFile 出错且 code==='ENOENT' 时返回 200 {ok:true,entries:[],count:0};其他读错误记 logger.error 并返回 500 {ok:false,error:'read_failed'}。POST appendFile 出错记 logger.error 并返回 500 {ok:false,error:'write_failed'}。 + +来源:[jiuwenswarm/channels/web/frontend/vite.config.ts:L368–L382](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/vite.config.ts#L368-L382), [jiuwenswarm/channels/web/frontend/vite.config.ts:L429–L436](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/vite.config.ts#L429-L436) + + + + + +**每次 dev 启动清空日志便于排查,但代价是该文件中的历史条目被覆盖** +设计推断(非作者历史意图): + +configureServer 里 mkdirSync 后 writeFileSync(logFile,'') 清空 ws-dev.log,注释说明是为避免历史数据干扰排查(收益)。成本(推断):GET 走 readFile 全量读取再 slice(-limit),日志增长时读取与解析开销随之增加;且清空使该文件中此前记录的条目不再可查。 + +来源:[jiuwenswarm/channels/web/frontend/vite.config.ts:L355–L367](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/vite.config.ts#L355-L367), [jiuwenswarm/channels/web/frontend/vite.config.ts:L383–L398](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/vite.config.ts#L383-L398) + + + diff --git a/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-frontend-incremental-lint-gate.md b/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-frontend-incremental-lint-gate.md index b44dbc01..7afb7c77 100644 --- a/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-frontend-incremental-lint-gate.md +++ b/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-frontend-incremental-lint-gate.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs:L1-L5, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs:L16-L22, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs:L28-L31, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs:L33-L46, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs:L7-L8, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs:L26-L26, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs:L54-L61, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs:L9-L10, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs:L22-L22, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs:L28-L48, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs:L49-L72] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs:L1-L5, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs:L16-L22, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs:L28-L31, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs:L33-L46, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs:L7-L8, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs:L26-L26, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs:L54-L61, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs:L9-L10, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs:L22-L22, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs:L28-L48, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs:L49-L72, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs:L11-L15, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs:L75-L81, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs:L36-L45] feature: "frontend-incremental-lint-gate" entry_points: ["jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs"] source_globs: ["jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs"] @@ -60,3 +60,12 @@ cwd 固定为脚本目录的上一级(frontend 根),git 与路径解析均 + + +**lint-changed 脚本的参数契约与非零退出(有新增诊断时)** +可选参数仅 `--base `,缺省 `HEAD`,由 `git rev-parse --verify ^{commit}` 解析;参数形式不符时抛出 Usage 错误终止。循环结束后若 introduced 非空,打印 stylish 格式结果并将 `process.exitCode` 置 1(L75-77),随后顺序输出 checked/新增/既有计数摘要(L79-81);该摘要仅在执行到达此处时打印——参数错误(L13)或被重新抛出的 Git 失败(L44)会提前终止。 + +来源:[jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs:L11–L15](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs#L11-L15), [jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs:L75–L81](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs#L75-L81), [jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs:L36–L45](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/scripts/lint-changed.mjs#L36-L45) + + + diff --git a/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-rsi-experiment-ui.md b/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-rsi-experiment-ui.md index 4e3c624e..8072af0c 100644 --- a/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-rsi-experiment-ui.md +++ b/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-rsi-experiment-ui.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/rsi/RsiPage.tsx:L28-L41, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/rsi/RsiPage.tsx:L58-L76, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/rsi/components/ConfigInfoDialog.tsx:L39-L65, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/rsi/components/CreateExperimentDialog.tsx:L105-L112, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/rsi/RsiPage.tsx:L50-L56, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/rsi/RsiPage.tsx:L78-L78, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/rsi/components/CreateExperimentDialog.tsx:L89-L107, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/rsi/components/CreateExperimentDialog.tsx:L114-L132] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/rsi/RsiPage.tsx:L28-L41, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/rsi/RsiPage.tsx:L58-L76, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/rsi/components/ConfigInfoDialog.tsx:L39-L65, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/rsi/components/CreateExperimentDialog.tsx:L105-L112, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/rsi/RsiPage.tsx:L50-L56, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/rsi/RsiPage.tsx:L78-L78, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/rsi/components/CreateExperimentDialog.tsx:L89-L107, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/rsi/components/CreateExperimentDialog.tsx:L114-L132, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/rsi/useRsiEvents.ts:L17-L41, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/rsi/RsiPage.tsx:L28-L34] feature: "rsi-experiment-ui" entry_points: ["jiuwenswarm/channels/web/frontend/src/features/rsi/RsiPage.tsx", "jiuwenswarm/channels/web/frontend/src/features/rsi/components/ConfigInfoDialog.tsx", "jiuwenswarm/channels/web/frontend/src/features/rsi/components/CreateExperimentDialog.tsx"] source_globs: ["jiuwenswarm/channels/web/frontend/src/features/rsi/RsiPage.tsx", "jiuwenswarm/channels/web/frontend/src/features/rsi/components/ConfigInfoDialog.tsx", "jiuwenswarm/channels/web/frontend/src/features/rsi/components/CreateExperimentDialog.tsx", "jiuwenswarm/agents/harness/common/rsi/artifact_adapter.py", "jiuwenswarm/channels/web/frontend/src/features/rsi/components/RsiDetail.tsx", "jiuwenswarm/channels/web/frontend/src/features/rsi/components/RsiRail.tsx", "jiuwenswarm/channels/web/frontend/src/features/rsi/rsiStore.ts", "jiuwenswarm/channels/web/frontend/src/features/rsi/featureConfig.ts", "jiuwenswarm/channels/web/frontend/src/features/rsi/types.ts", "jiuwenswarm/channels/web/frontend/src/features/rsi/styles/rsi.css", "jiuwenswarm/channels/web/frontend/src/features/rsi/components/RsiIntroduction.tsx", "jiuwenswarm/channels/web/frontend/src/features/rsi/mockData.ts", "jiuwenswarm/channels/web/frontend/src/features/rsi/rsiPresentation.ts", "jiuwenswarm/channels/web/frontend/src/features/rsi/components/RsiSelectedInfo.tsx", "jiuwenswarm/agents/harness/common/rsi/paper_provider.py", "jiuwenswarm/agents/harness/common/rsi/projector.py", "jiuwenswarm/channels/web/frontend/src/features/rsi/useRsiEvents.ts"] @@ -60,3 +60,12 @@ useMemo 在每次表单字段变化时重算 validationErrors:name 与 optimiz + + +**useRsiEvents 仅在 enabled 时订阅 webClient 三类 RSI 事件并回写 rsiStore** +回调将 payload 经 normalize* 归一后按真值守卫调用 store 的 applyStatusChanged/applyProgress/applyTreeDelta;effect 返回的清理函数依次注销三个监听。RsiPage 挂载期间以 useRsiEvents(true) 开启订阅。 + +来源:[jiuwenswarm/channels/web/frontend/src/features/rsi/useRsiEvents.ts:L17–L41](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/features/rsi/useRsiEvents.ts#L17-L41), [jiuwenswarm/channels/web/frontend/src/features/rsi/RsiPage.tsx:L28–L34](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/features/rsi/RsiPage.tsx#L28-L34) + + + diff --git a/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-share-image-export.md b/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-share-image-export.md index 5909df99..19c74ec1 100644 --- a/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-share-image-export.md +++ b/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-share-image-export.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/share_image_export.py:L86-L98, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/share_image_export.py:L101-L117, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/app_web.py:L1226-L1232, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/share_image_export.py:L44-L52, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/share_image_export.py:L210-L210, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/share_image_export.py:L69-L98, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/channels/web/test_share_image_export.py:L614-L625, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/channels/web/test_share_image_export.py:L525-L531, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/channels/web/test_share_image_export.py:L516-L522, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/share_image_export.py:L196-L208] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/share_image_export.py:L86-L98, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/share_image_export.py:L101-L117, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/app_web.py:L1226-L1232, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/share_image_export.py:L44-L52, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/share_image_export.py:L210-L210, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/share_image_export.py:L69-L98, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/channels/web/test_share_image_export.py:L614-L625, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/channels/web/test_share_image_export.py:L525-L531, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/channels/web/test_share_image_export.py:L516-L522, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/share_image_export.py:L196-L208, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/share_image_export.py:L212-L235, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/shareImageExport.tsx:L1466-L1478] feature: "share-image-export" entry_points: ["jiuwenswarm/channels/web/frontend/vite.config.ts", "jiuwenswarm/channels/web/share_image_export.py"] source_globs: ["jiuwenswarm/channels/web/frontend/vite.config.ts", "jiuwenswarm/channels/web/share_image_export.py", "jiuwenswarm/channels/web/frontend/src/features/shareImageExport.tsx", "jiuwenswarm/channels/web/frontend/src/features/shareImageArchive.ts", "jiuwenswarm/channels/web/frontend/src/features/shareImageExport.css", "jiuwenswarm/channels/web/app_web.py", "jiuwenswarm/channels/web/frontend/src/features/shareImageJob.ts", "jiuwenswarm/channels/web/frontend/src/features/shareImagePng.worker.ts", "jiuwenswarm/channels/web/frontend/src/features/shareImagePngEncoder.ts", "jiuwenswarm/channels/web/frontend/src/App.tsx", "jiuwenswarm/channels/web/frontend/src/main.tsx", "jiuwenswarm/channels/web/frontend/src/features/shareImageRaster.ts"] @@ -69,3 +69,12 @@ test_render_runner_not_initialized_fails_within_init_timeout drives the real sha + + +**render_share_image resolves browser config, then reports launching and starts headless Chromium with a 900×900 context** +在 render_share_image 内,先调用 _configured_browser()(L220),再根据 executable_path 是否为真组装 launch_options(设 executable_path,否则设 channel,且 headless: True,L221–L225),此后才执行 report("launching")(L229)——因此配置解析/失败可发生在 launching 回调之前。随后 sync_playwright 里 chromium.launch(**launch_options) 启动浏览器并 new_context(viewport 900×900, accept_downloads=True)。report 是条件回调:仅当 on_phase 非 None 时转发 phase。前端侧 ShareImageExportRunner 的 useEffect 回调先把 window.__SHARE_IMAGE_EXPORT_STATE 置为 { status: 'loading_snapshot' },再 fetch /share-api/jobs//snapshot(cache: 'no-store')。 + +来源:[jiuwenswarm/channels/web/share_image_export.py:L212–L235](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/share_image_export.py#L212-L235), [jiuwenswarm/channels/web/frontend/src/features/shareImageExport.tsx:L1466–L1478](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/features/shareImageExport.tsx#L1466-L1478) + + + diff --git a/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-web-asset-publish-flow.md b/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-web-asset-publish-flow.md index 8a9ce3fa..d155f16f 100644 --- a/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-web-asset-publish-flow.md +++ b/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-web-asset-publish-flow.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/services/assetPublishApi.ts:L28-L38, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/hooks/useAssetPublish.ts:L39-L61, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/assetPublishState.ts:L7-L15, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/assetPublishState.ts:L47-L61, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/assetPublishErrors.ts:L13-L33, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/tests/assetPublishDrawer.test.mjs:L317-L331, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/assetPublishEvents.ts:L1-L4, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/services/assetPublishApi.ts:L10-L38, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/assetPublishState.ts:L23-L41] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/services/assetPublishApi.ts:L28-L38, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/hooks/useAssetPublish.ts:L39-L61, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/assetPublishState.ts:L7-L15, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/assetPublishState.ts:L47-L61, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/assetPublishErrors.ts:L13-L33, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/tests/assetPublishDrawer.test.mjs:L317-L331, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/assetPublishEvents.ts:L1-L4, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/services/assetPublishApi.ts:L10-L38, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/assetPublishState.ts:L23-L41, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/services/assetPublishApi.ts:L10-L19, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/services/assetPublishApi.ts:L27-L38, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/utils/gitcodeOAuth.ts:L32-L47, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/hooks/useAssetPublish.ts:L29-L30] feature: "web-asset-publish-flow" entry_points: ["jiuwenswarm/channels/web/frontend/src/hooks/useAssetPublish.ts"] source_globs: ["jiuwenswarm/channels/web/frontend/src/hooks/useAssetPublish.ts", "jiuwenswarm/channels/web/frontend/src/types/assetPublish.ts", "jiuwenswarm/channels/web/frontend/src/features/assetPublication.ts", "jiuwenswarm/channels/web/frontend/src/features/assetPublishErrors.ts", "jiuwenswarm/channels/web/frontend/src/features/assetPublishEvents.ts", "jiuwenswarm/channels/web/frontend/src/features/assetPublishState.ts"] @@ -69,3 +69,12 @@ assetPublishDrawer.test.mjs 用 assetPublishApi.describe/status 桩返回 queued + + +**assetPublishApi 的 describe/prepare/commit/status/records 五方法经共享 request 注入 OAuth 凭据并依赖 sessionStorage 读取** +所示 assetPublishApi.ts 中 describe、prepare、commit、status、records 五个方法都经共享 request 调 webRequest,方法名拼接为 `assets.publish.${method}`,并统一附加 auth(getStoredOAuthToken/getStoredOAuthProvider)与 timeoutMs 75_000。凭据读取依赖 sessionStorage:getStoredOAuthToken 读取异常时返回 null,getStoredOAuthProvider 仅在归一化为 'github' 时返回 'github',否则(含异常)回退 'gitcode'。useAssetPublish.ts L29 以 `${provider}:${token || ''}` 构造作用域键,token 为 null 时用空字符串。此范围不含 localStatus 等未展示分支。 + +来源:[jiuwenswarm/channels/web/frontend/src/services/assetPublishApi.ts:L10–L19](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/services/assetPublishApi.ts#L10-L19), [jiuwenswarm/channels/web/frontend/src/services/assetPublishApi.ts:L27–L38](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/services/assetPublishApi.ts#L27-L38), [jiuwenswarm/channels/web/frontend/src/utils/gitcodeOAuth.ts:L32–L47](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/utils/gitcodeOAuth.ts#L32-L47), [jiuwenswarm/channels/web/frontend/src/hooks/useAssetPublish.ts:L29–L30](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/hooks/useAssetPublish.ts#L29-L30) + + + diff --git a/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-web-i18n-zh-en.md b/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-web-i18n-zh-en.md index 258e6cc4..27db67a1 100644 --- a/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-web-i18n-zh-en.md +++ b/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-web-i18n-zh-en.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/i18n/index.ts:L15-L27, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/i18n/index.ts:L1-L14, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/i18n/index.ts:L22-L27, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/i18n/index.ts:L1-L28, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/i18n/index.ts:L30-L30, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/tests/fixtures/settings-extension/extensionDemoMain.tsx:L17-L20, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/i18n/index.ts:L15-L28] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/i18n/index.ts:L15-L27, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/i18n/index.ts:L1-L14, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/i18n/index.ts:L22-L27, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/i18n/index.ts:L1-L28, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/i18n/index.ts:L30-L30, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/tests/fixtures/settings-extension/extensionDemoMain.tsx:L17-L20, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/i18n/index.ts:L15-L28, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/tests/inputAreaPermissionMerge.test.mjs:L90-L94, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/tests/inputAreaPermissionMerge.test.mjs:L149-L161, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/tests/inputAreaPermissionMerge.test.mjs:L229-L247, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/i18n/index.ts:L1-L30] feature: "web-i18n-zh-en" entry_points: ["jiuwenswarm/channels/web/frontend/src/i18n/index.ts"] source_globs: ["jiuwenswarm/channels/web/frontend/src/i18n/index.ts", "jiuwenswarm/channels/web/frontend/src/App.tsx"] @@ -69,3 +69,12 @@ detection.order 仅含 'localStorage'(L25),不会读取 navigator;注释 + + +**现有 DOM 测试以 zh/en 运行打包后的 i18n 模块并断言 tooltip 文案已翻译(仅覆盖运行时翻译使用)** +tests/inputAreaPermissionMerge.test.mjs 导入打包产物中的生产 i18n 模块(i18n/index.js),mount 前调用 i18n.changeLanguage(language),并对 'zh' 与 'en' 各跑一个用例;断言 tooltip.textContent 等于 i18n.t('chat.config.mode.clusterDesc') 且不等于未翻译键名。该测试验证切换语言后 t() 产出翻译文案,不覆盖 i18n 初始化的 fallbackLng/detection 默认路径。 + +来源:[jiuwenswarm/channels/web/frontend/tests/inputAreaPermissionMerge.test.mjs:L90–L94](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/tests/inputAreaPermissionMerge.test.mjs#L90-L94), [jiuwenswarm/channels/web/frontend/tests/inputAreaPermissionMerge.test.mjs:L149–L161](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/tests/inputAreaPermissionMerge.test.mjs#L149-L161), [jiuwenswarm/channels/web/frontend/tests/inputAreaPermissionMerge.test.mjs:L229–L247](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/tests/inputAreaPermissionMerge.test.mjs#L229-L247), [jiuwenswarm/channels/web/frontend/src/i18n/index.ts:L1–L30](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/i18n/index.ts#L1-L30) + + + diff --git a/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-web-native-directory-picker.md b/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-web-native-directory-picker.md index a71acff8..78cc203d 100644 --- a/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-web-native-directory-picker.md +++ b/knowledge/repos/jiuwenswarm/components/web-frontend/feature-depth-web-native-directory-picker.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/directory_picker.py:L296-L309, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/directory_picker.py:L427-L443, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/directory_picker.py:L290-L295, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/directory_picker.py:L339-L346, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/directory_picker.py:L501-L520] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/directory_picker.py:L296-L309, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/directory_picker.py:L427-L443, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/directory_picker.py:L290-L295, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/directory_picker.py:L339-L346, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/directory_picker.py:L501-L520, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L3603-L3620, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/directory_picker.py:L415-L425, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/directory_picker.py:L355-L370, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/gateway/test_app_web_handlers.py:L484-L541] feature: "web-native-directory-picker" entry_points: ["jiuwenswarm/channels/web/directory_picker.py"] source_globs: ["jiuwenswarm/channels/web/directory_picker.py"] @@ -51,3 +51,30 @@ docstring 声明在独立子进程中运行 tkinter 以保证 Tk 位于该进程 + + +**path.select_file 处理器经 asyncio.to_thread 调用 select_file_native,异常时回 UNSUPPORTED** +处理器先把 initial_dir 去空白;仅当 initial_path 是字符串且 strip() 后非空白时,用其 expanduser 后的父目录覆盖 resolved_initial_dir(L3604–L3605)。import 在 try 外,随后在 try 内用 asyncio.to_thread 调用 select_file_native 并传入 initial_dir 与 title;捕获任何 Exception 后记录 warning,并通过 channel.send_response 发送 ok=False、code="UNSUPPORTED" 的响应后返回。 + +来源:[jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L3603–L3620](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py#L3603-L3620) + + + + + +**Linux 目录后端链依赖 shutil.which 探测,tkinter 子进程后端始终追加** +_select_directory_linux 用 shutil.which 依次探测 zenity/kdialog/yad,探测到才加入后端列表,tkinter 子进程后端总是无条件追加(目录链 L415–L425)。tkinter 文件子进程后端复制 os.environ 并设置 JIUWEN_FILE_PICKER_INITIAL/JIUWEN_FILE_PICKER_TITLE 传参,docstring 说明 Tk 在独立进程的主线程创建(L355–L370);未展示子进程启动代码本身。 + +来源:[jiuwenswarm/channels/web/directory_picker.py:L415–L425](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/directory_picker.py#L415-L425), [jiuwenswarm/channels/web/directory_picker.py:L355–L370](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/directory_picker.py#L355-L370) + + + + + +**单测用 monkeypatch 假体验证 path.select_file 的参数转发与取消/成功响应(未触真实 OS 对话框)** +test_path_select_file_returns_selected_path 将 select_file_native 替换为 fake,断言传入的 initial_dir 为 initial_path 的父目录、title 原样转发,且响应 payload 为 {"path": selected_path, "cancelled": False}(L484–L521);test_path_select_file_returns_cancelled 将其替换为返回 None 的 lambda,断言 ok=True 且 payload 为 {"path": None, "cancelled": True}(L524–L541)。断言仅覆盖处理器对 fake 的转发,不执行真实本机选择器。 + +来源:[tests/unit_tests/gateway/test_app_web_handlers.py:L484–L541](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/gateway/test_app_web_handlers.py#L484-L541) + + + From 465f3515ca350e4c5926240f0e405294c6d0913b Mon Sep 17 00:00:00 2001 From: tzhouam Date: Wed, 7 Oct 2026 19:31:19 +0800 Subject: [PATCH 4/5] Complete JiuwenSwarm knowledge acceptance and cache replay --- doc/architecture/SPEC/kb_service.md | 2 +- doc/architecture/SPEC/knowledge_service.md | 10 +- .../jiuwenswarm-init-completion-20261007.json | 1392 +++++++++++++++++ .../jiuwenswarm-init-completion-20261007.md | 108 ++ .../components/agent-runtime/_index.md | 4 + ...ture-runtime-agent-definition-execution.md | 12 +- .../components/agent-runtime/knowledge.md | 12 +- .../components/agent-server-runtime/_index.md | 2 + .../components/agents-team/_index.md | 42 + .../feature-command-execution-tool.md | 30 +- .../feature-depth-xiaoyi-calendar-tools.md | 11 +- .../feature-depth-xiaoyi-call-phone-tool.md | 13 +- .../feature-depth-xiaoyi-collection-tools.md | 11 +- .../feature-depth-xiaoyi-contact-search.md | 11 +- .../feature-depth-xiaoyi-location-tool.md | 11 +- .../feature-depth-xiaoyi-note-tools.md | 11 +- ...eature-depth-xiaoyi-photo-gallery-tools.md | 11 +- ...-depth-xiaoyi-pushdata-store-and-viewer.md | 11 +- ...eature-depth-xiaoyi-timestamp-utc8-tool.md | 11 +- .../agents-team/feature-dynamic-memory-cli.md | 12 +- .../feature-llm-wiki-knowledge-base.md | 30 +- .../agents-team/feature-pdf-reading-tool.md | 12 +- .../agents-team/feature-sdd-design-rail.md | 12 +- .../agents-team/feature-xiaoyi-alarm-crud.md | 30 +- .../feature-xiaoyi-calendar-tools.md | 22 +- .../feature-xiaoyi-location-tool.md | 12 +- .../feature-xiaoyi-save-to-phone-tools.md | 14 +- .../components/browser-client/knowledge.md | 14 +- .../components/config-resources/_index.md | 86 + ...ature-agent-template-layered-validation.md | 14 +- .../feature-arxiv-visual-extraction.md | 12 +- .../feature-ascend-chrome-trace-generator.md | 20 +- .../feature-audit-integrity-hmac-signing.md | 20 +- .../feature-audit-report-html-renderer.md | 12 +- .../feature-deepsearch-research-pipeline.md | 28 +- .../feature-depth-arxiv-visual-extraction.md | 13 +- .../feature-huawei-maas-apikey-creation.md | 12 +- .../feature-huawei-realname-account-check.md | 12 +- .../feature-local-doc-ocr-offline.md | 20 +- .../feature-maas-auto-open-models.md | 14 +- .../feature-plugin-package-initializer.md | 12 +- ...eature-plugin-package-layered-validator.md | 12 +- .../feature-ppt-deck-finalize.md | 20 +- .../feature-ppt-execution-lock-validator.md | 12 +- .../feature-ppt-figure-panel-layout.md | 20 +- .../feature-pptx-structural-audit.md | 20 +- .../feature-rsi-dataset-folder-check.md | 12 +- .../feature-skill-page-scrape-blocks.md | 12 +- .../feature-sop-structure-extraction.md | 12 +- .../feature-xlsx-add-computed-column.md | 12 +- .../feature-xlsx-insert-row.md | 12 +- .../feature-xlsx-reader-structural-diff.md | 12 +- .../knowledge-config-resources.md | 12 +- .../components/cron-scheduling/knowledge.md | 12 +- .../components/extensions-plugins/_index.md | 8 + ...eature-video-agent-managed-task-service.md | 14 +- .../feature-yuanrong-agent-file-transfer.md | 28 +- .../feature-yuanrong-faas-invocation.md | 12 +- .../extensions-plugins/knowledge.md | 28 +- .../components/gateway-channels/_index.md | 18 + ...ure-at-file-reference-inlining-b1a822e1.md | 12 +- .../feature-gateway-config-hot-reload.md | 14 +- .../feature-gateway-health-check.md | 20 +- .../feature-gateway-server-multi-route-ws.md | 20 +- ...ure-im-attachment-persist-hook-969909e1.md | 12 +- .../feature-im-channel-hot-reconfig.md | 20 +- .../feature-thirdagent-list-switch.md | 12 +- .../knowledge-gateway-channels.md | 20 +- .../components/gateway-channels/knowledge.md | 12 +- .../components/ide-clients/_index.md | 4 + .../feature-ide-file-edit-diff-apply.md | 14 +- .../feature-ide-turn-rewind-snapshot.md | 12 +- .../components/ide-vscode/_index.md | 2 + .../feature-ide-terminal-command-mirror.md | 36 +- .../components/launch/knowledge.md | 12 +- .../components/observability/knowledge.md | 12 +- .../knowledge-packaging-deploy.md | 12 +- .../protocols/knowledge-protocols.md | 12 +- .../components/sandbox-runtime/knowledge.md | 12 +- .../symphony-orchestration/knowledge.md | 12 +- .../components/web-frontend/_index.md | 22 + .../feature-chat-session-stats-dashboard.md | 12 +- .../feature-context-usage-indicator.md | 20 +- .../web-frontend/feature-rsi-experiment-ui.md | 38 +- .../feature-share-image-export.md | 20 +- .../feature-web-asset-publish-flow.md | 12 +- .../web-frontend/feature-web-i18n-zh-en.md | 12 +- .../knowledge_service/pinned_claims.py | 86 +- test/test_kb_pinned_observer_cache.py | 173 ++ 89 files changed, 2948 insertions(+), 165 deletions(-) create mode 100644 eval/knowledge-depth/jiuwenswarm-init-completion-20261007.json create mode 100644 eval/knowledge-depth/jiuwenswarm-init-completion-20261007.md create mode 100644 test/test_kb_pinned_observer_cache.py diff --git a/doc/architecture/SPEC/kb_service.md b/doc/architecture/SPEC/kb_service.md index c8282863..8e2d2673 100644 --- a/doc/architecture/SPEC/kb_service.md +++ b/doc/architecture/SPEC/kb_service.md @@ -1,6 +1,6 @@ # kb_service/ —— 规范 - + `知识服务核心:仓库配置、账本、outbox、CLI · refactor-status: new` diff --git a/doc/architecture/SPEC/knowledge_service.md b/doc/architecture/SPEC/knowledge_service.md index d3ac4c8f..1296f46f 100644 --- a/doc/architecture/SPEC/knowledge_service.md +++ b/doc/architecture/SPEC/knowledge_service.md @@ -1,11 +1,19 @@ # knowledge_service/ — provider curation components - + Pinned source identities and depth markers accept full SHA-1 or SHA-256 Git commits. Evidence bodies, stored hashes and native approval semantics remain unchanged; accepting a wider object identity never renews an old approval. +`PinnedObserver` reuses successful Git tree and blob reads by full commit SHA +and path within one observer. Concurrent readers share its lock and cache; +mutable references are resolved on each call before choosing a cache key, and +returned top-level sets cannot mutate cached values. A fresh observer reads +again, read failures are never cached, and live PR metadata is always fetched. +This avoids repeated Git subprocesses during checkpoint evidence replay while +preserving the same source text and evidence hashes. + The provider owns knowledge curation beneath the public SDK v1 facade. `KnowledgeCurator` composes four domain components over one explicit work checkout: `CatalogMixin` discovers contained owner rule pages and their diff --git a/eval/knowledge-depth/jiuwenswarm-init-completion-20261007.json b/eval/knowledge-depth/jiuwenswarm-init-completion-20261007.json new file mode 100644 index 00000000..f78922e9 --- /dev/null +++ b/eval/knowledge-depth/jiuwenswarm-init-completion-20261007.json @@ -0,0 +1,1392 @@ +{ + "amount": { + "current": { + "markdown_bytes": 6803739, + "markdown_files": 958 + }, + "interpretation": "Markdown文件体积包括元数据、引用与证明;不是模型实际收到的上下文量。", + "preview": { + "markdown_bytes": 6321054, + "markdown_files": 957 + }, + "published": { + "markdown_bytes": 5346963, + "markdown_files": 864 + } + }, + "artifacts": { + "depth_archive_with_zero_task_declarations": { + "bytes": 2994812, + "path": ".kb-jiuwenswarm-finish-20261007/final-audit/depth-native-archive-manifest.json", + "sha256": "bad89a62a30fc5de4b1a7fb944269f17f39a8df3578647d3eaaef86f7a577763" + }, + "depth_native_audit": { + "bytes": 1259586, + "path": ".kb-jiuwenswarm-finish-20261007/final-audit/native-approvals-1178.json", + "sha256": "13548385cecd19fe76e37155ac864ada93bb22bf4cbcda17f89feba691bb2ad1" + }, + "foundation_last_attempt_unknowns": { + "bytes": 139540, + "path": ".kb-jiuwenswarm-finish-20261007/foundation/foundation-unknown-33-20261007-v3.json", + "sha256": "c1953d712992e6d303c0fc12b94718359ca255d22a39d18adf11945435502f5c" + }, + "foundation_native_audit": { + "bytes": 816287, + "path": ".kb-jiuwenswarm-finish-20261007/foundation/foundation-final-audit-20261007.json", + "sha256": "73f4a59ad06647229db9d388c1477e86146bd8fa9a94b4fd31e53944710822ab" + }, + "knowledge_files_manifest": { + "bytes": 142811, + "path": ".kb-jiuwenswarm-finish-20261007/final-audit/final-acceptance/candidate-files-manifest.json", + "sha256": "ff959e125a84271cf9513a9a9d327086dd8f22b7ba3d7c2a67e91070f502704c" + }, + "local_source_replay_benchmark": { + "bytes": 9869, + "path": ".kb-jiuwenswarm-finish-20261007/foundation/cache-proposal/local-replay-benchmark-final-candidate.json", + "sha256": "b245b55933e18db907162b984a626749ed714f535433fcfa13ef117c064fc861" + }, + "source_and_recognition_audit": { + "bytes": 638127, + "path": ".kb-jiuwenswarm-finish-20261007/final-audit/final-acceptance/source-and-recognition-audit.json", + "sha256": "fa9dff67776d8ebe8914fe81ad882e2cef252aff572cdbaed56b702f430da14e" + } + }, + "baseline": { + "depth_original_79": { + "denominator": 553, + "ratio": 0.9981916817359855, + "recognized": 552 + }, + "depth_rebased_to_173": { + "denominator": 1211, + "ratio": 0.4558216350123865, + "recognized": 552 + }, + "foundation": { + "complete_features": 108, + "denominator": 1038, + "recognized": 927, + "unknown_cells": 111 + }, + "unpublished_preview": { + "denominator": 1211, + "feature_count": 172, + "recognized": 1047 + } + }, + "catalog_features": 173, + "catalog_sha256": "e6c37a346cccdaff5404c26a21b5a88f733150b1e0835c4a533a332d20df68ed", + "created_at": "2026-10-07T11:27:54.963822+00:00", + "current": { + "all_seven_complete_features": 143, + "depth": { + "acceptance_mode": "lightweight", + "facet_counts": { + "api": { + "eligible_ratio": 0.976878612716763, + "eligible_recognized": 169, + "lightweight_recognized": 134, + "ratio": 0.976878612716763, + "recognized": 169, + "strict_recognized": 35, + "supported": 169, + "target_met": true, + "unknown": 4, + "verified_absent": 0 + }, + "configuration": { + "eligible_ratio": 0.9942196531791907, + "eligible_recognized": 172, + "lightweight_recognized": 121, + "ratio": 0.9942196531791907, + "recognized": 172, + "strict_recognized": 51, + "supported": 172, + "target_met": true, + "unknown": 1, + "verified_absent": 0 + }, + "dependencies": { + "eligible_ratio": 0.9710982658959537, + "eligible_recognized": 168, + "lightweight_recognized": 145, + "ratio": 0.9710982658959537, + "recognized": 168, + "strict_recognized": 23, + "supported": 168, + "target_met": true, + "unknown": 5, + "verified_absent": 0 + }, + "failure_modes": { + "eligible_ratio": 0.9710982658959537, + "eligible_recognized": 168, + "lightweight_recognized": 144, + "ratio": 0.9710982658959537, + "recognized": 168, + "strict_recognized": 24, + "supported": 168, + "target_met": true, + "unknown": 5, + "verified_absent": 0 + }, + "flow": { + "eligible_ratio": 0.9942196531791907, + "eligible_recognized": 172, + "lightweight_recognized": 150, + "ratio": 0.9942196531791907, + "recognized": 172, + "strict_recognized": 22, + "supported": 172, + "target_met": true, + "unknown": 1, + "verified_absent": 0 + }, + "tradeoffs": { + "eligible_ratio": 0.9884393063583815, + "eligible_recognized": 171, + "lightweight_recognized": 147, + "ratio": 0.9884393063583815, + "recognized": 171, + "strict_recognized": 24, + "supported": 171, + "target_met": true, + "unknown": 2, + "verified_absent": 0 + }, + "validation": { + "eligible_ratio": 0.9132947976878613, + "eligible_recognized": 158, + "lightweight_recognized": 130, + "ratio": 0.9132947976878613, + "recognized": 158, + "strict_recognized": 28, + "supported": 158, + "target_met": true, + "unknown": 15, + "verified_absent": 0 + } + }, + "lightweight_recognized_facets": 971, + "per_facet_gt": 0.9, + "recognized_complete_features": 143, + "recognized_facet_ratio": 0.9727497935590421, + "recognized_facets": 1178, + "recognized_feature_count": 173, + "strict_recognized_facets": 207, + "target_met": true, + "total_facets": 1211, + "total_features": 173, + "validation_kind_counts": { + "automated_runtime": 52, + "automated_source_text": 1, + "documented_manual": 51, + "helper_unit": 26, + "unclassified": 28 + } + }, + "depth_evidence_file_ratio": 0.16462028194633924, + "depth_evidence_production_files": 362, + "dimensions": [ + { + "eligible_ratio": 0.976878612716763, + "eligible_recognized": 169, + "facet": "api", + "lightweight_recognized": 134, + "name": "API 契约", + "ratio": 0.976878612716763, + "recognized": 169, + "strict_recognized": 35, + "supported": 169, + "target_met": true, + "unknown": 4, + "verified_absent": 0 + }, + { + "eligible_ratio": 0.9942196531791907, + "eligible_recognized": 172, + "facet": "configuration", + "lightweight_recognized": 121, + "name": "配置与默认行为", + "ratio": 0.9942196531791907, + "recognized": 172, + "strict_recognized": 51, + "supported": 172, + "target_met": true, + "unknown": 1, + "verified_absent": 0 + }, + { + "eligible_ratio": 0.9710982658959537, + "eligible_recognized": 168, + "facet": "dependencies", + "lightweight_recognized": 145, + "name": "依赖与关联功能", + "ratio": 0.9710982658959537, + "recognized": 168, + "strict_recognized": 23, + "supported": 168, + "target_met": true, + "unknown": 5, + "verified_absent": 0 + }, + { + "eligible_ratio": 0.9710982658959537, + "eligible_recognized": 168, + "facet": "failure_modes", + "lightweight_recognized": 144, + "name": "失败与降级行为", + "ratio": 0.9710982658959537, + "recognized": 168, + "strict_recognized": 24, + "supported": 168, + "target_met": true, + "unknown": 5, + "verified_absent": 0 + }, + { + "eligible_ratio": 0.9942196531791907, + "eligible_recognized": 172, + "facet": "flow", + "lightweight_recognized": 150, + "name": "执行流程", + "ratio": 0.9942196531791907, + "recognized": 172, + "strict_recognized": 22, + "supported": 172, + "target_met": true, + "unknown": 1, + "verified_absent": 0 + }, + { + "eligible_ratio": 0.9884393063583815, + "eligible_recognized": 171, + "facet": "tradeoffs", + "lightweight_recognized": 147, + "name": "设计取舍", + "ratio": 0.9884393063583815, + "recognized": 171, + "strict_recognized": 24, + "supported": 171, + "target_met": true, + "unknown": 2, + "verified_absent": 0 + }, + { + "eligible_ratio": 0.9132947976878613, + "eligible_recognized": 158, + "facet": "validation", + "lightweight_recognized": 130, + "name": "验证与测试入口", + "ratio": 0.9132947976878613, + "recognized": 158, + "strict_recognized": 28, + "supported": 158, + "target_met": true, + "unknown": 15, + "verified_absent": 0 + } + ], + "foundation": { + "complete_features": 142, + "denominator": 1038, + "entry_evidence_missing_features": [ + "context-usage-indicator", + "ide-file-edit-diff-apply" + ], + "facet_complete_features": 144, + "incomplete_features": 31, + "missing_by_facet": { + "api": 4, + "architecture": 6, + "configuration": 3, + "features": 3, + "tradeoffs": 12, + "validation": 5 + }, + "ratio": 0.9682080924855492, + "recognized": 1005, + "unknown_cells": 33, + "unknown_features": 29 + }, + "structure": { + "covered": 2058, + "ratio": 0.9358799454297408, + "stale_contracts": [], + "target": 0.85, + "total": 2199 + } + }, + "fresh_pr_review_experiments": 0, + "knowledge_checkout_base_sha": "2d54c48fe31f83df298dec94a26e8fea30d8c95d", + "knowledge_target_met": true, + "knowledge_tool_validation": { + "CI": "see_pull_request", + "final_full_suite": "frozen_candidate_rerun_pending_at_report", + "fresh_SDK_related_rerun": { + "passed": 35 + }, + "initial_full_suite": { + "failed": 6, + "passed": 3929, + "reason": "运行中组装基础知识引发资源版本变化;资源修订校验按设计拒绝过期上下文。该结果保留。", + "skipped": 18 + }, + "pinned_cache_tests": { + "passed": 26 + }, + "post_integration_knowledge_tests": { + "passed": 140 + }, + "supplemental_pure_tests": { + "passed": 6 + }, + "wheel_and_installed_SDK_smoke": "passed" + }, + "local_source_read_reuse": { + "cache_hits": 9849, + "successful_reads": 374 + }, + "local_source_replay_benchmark": { + "claims": { + "frozen_runtime_modified": false, + "full_returned_hashes_equal": true, + "model_calls": 0, + "model_review_accuracy_measured": false, + "pr_review_speed_measured": false + }, + "files": { + "benchmark_script_sha256": "c578580fb232c0951611e066b007af9967801fbcd6ae3485f8de6cc129e759d5", + "original_sha256": "e10007edd42072bee0b4ee415a9581e5c7a30d96f32e2a704f6d2f687337a6ee", + "proposal_sha256": "aa7fcbfca6f6a616a05dd697a9517c422050e1785e0c58baa9440f6276b646e5" + }, + "measured_at": "2026-10-07T11:24:42.641248+00:00", + "median_local_replay_reduction_pct": 89.68950424563796, + "scope": { + "distinct_real_feature_evidence_paths": 20, + "repetitions_per_path": 10, + "runs_per_group": 3 + }, + "source_sha": "f0a69728c96b5961d993449f1a901cbd2f4dac5b", + "summary": { + "original": { + "median_wall_time_s": 7.002177724614739, + "subprocesses_per_run": [ + 401, + 401, + 401 + ], + "total_subprocesses": 1203 + }, + "proposed": { + "median_wall_time_s": 0.7219592370092869, + "subprocesses_per_run": [ + 41, + 41, + 41 + ], + "total_subprocesses": 123 + } + } + }, + "native": { + "archive": { + "actual_physical_directories": 73, + "bytes": 1698429131, + "files": 11959, + "historical_status_note": "历史归档中的失败、取消和未结算调用保留;不能据此称当前终态批次未完成。", + "manifest": { + "bytes": 3921872, + "path": ".kb-jiuwenswarm-finish-20261007/final-audit/final-acceptance/native-archive-manifest.json", + "sha256": "ff3efc1878589e9ace5d656e5847d66f5bfd2207f02af235e29f830d821b4a19" + } + }, + "audit_new_model_calls": 0, + "fees": "unknown", + "phases": [ + { + "elapsed_seconds": 4602.618827, + "exit_code": 0, + "fees": "unknown", + "finished_at": "2026-10-07T11:02:08.774850+00:00", + "phase": "foundation", + "record": { + "bytes": 932, + "path": ".kb-jiuwenswarm-finish-20261007/foundation-process.json", + "sha256": "81e7bf46eba1da1e937ad06ccfdc84a44df58a2cbfbb27da1499892a0a167cf0" + }, + "started_at": "2026-10-07T09:45:26.156023+00:00" + }, + { + "elapsed_seconds": 1858.018482, + "exit_code": 0, + "fees": "unknown", + "finished_at": "2026-10-07T10:16:24.265941+00:00", + "phase": "depth", + "record": { + "bytes": 1870, + "path": ".kb-jiuwenswarm-finish-20261007/depth-process.json", + "sha256": "e3c1d94a8e9550cb36a49f3fc686c0d2b9ff6de5aca7bab6ab02940b04432ed0" + }, + "started_at": "2026-10-07T09:45:26.247459+00:00" + }, + { + "elapsed_seconds": 257.586395, + "exit_code": 0, + "fees": "unknown", + "finished_at": "2026-10-07T10:35:05.586541+00:00", + "phase": "validation-evidence-revision", + "record": { + "bytes": 1101, + "path": ".kb-jiuwenswarm-finish-20261007/validation-revision-process.json", + "sha256": "58f3e5c0dff804771e88a0e3dd5609a9cf92d2a13f262d44977f95bbdec46eec" + }, + "started_at": "2026-10-07T10:30:48.000146+00:00" + } + ], + "supplemental": { + "automatic_corrections": 0, + "calls_by_role": { + "generator": 16, + "judge": 16 + }, + "cumulative_rounds": 9, + "historical_rounds": 4, + "new_logical_round_limit": 1, + "outcomes": { + "fail": 4, + "pass": 10, + "unsure": 2 + }, + "preceding_rounds": 4, + "served_model_counts": { + "GLM-5.3": 16, + "unreported": 16 + }, + "tasks": 16, + "uncreated_empty_partitions": [ + 9, + 10, + 11 + ] + } + }, + "pr_accuracy_gain": "not_measured", + "pr_review_speed_gain": "not_measured", + "preservation": { + "published_depth": { + "checked": 552, + "edited": [], + "missing": [], + "passed": true, + "unchanged": 552 + }, + "published_foundation": { + "checked": 930, + "edited": [], + "missing": [], + "passed": true, + "unchanged": 930 + }, + "retained_preview_depth": { + "checked": 1047, + "edited": [], + "missing": [], + "passed": true, + "unchanged": 1047 + } + }, + "previous_catalog_features": 79, + "release_note": "本报告核对已审计候选;知识工具测试、CI及合并状态以本次PR记录为准。", + "runtime_tests_executed": false, + "schema": "jiuwenswarm-init-completion-public-v1", + "scope_interpretation": "声明范围已处理不等于所有功能均已发现。原79项功能552/553;本轮固定173项,使用1211分母。", + "shared_inventory_unknowns": { + "binary_text_read_failures": 4, + "counted_as_absence": false, + "test_parse_failures": 2 + }, + "source_audit_at": "2026-10-07T11:09:53.113528+00:00", + "source_sha": "f0a69728c96b5961d993449f1a901cbd2f4dac5b", + "status": "independently_audited_candidate", + "unknown": { + "depth": [ + { + "attempts": 4, + "facet": "dependencies", + "feature": "a2x-registry-client-sdk", + "latest_attempt_status": "fail", + "native_trace_id": "1791367945483-e477c95267b0", + "reason": "The constructor wiring and delete_dataset cleanup calls are supported by async_client.py:L39–L57 and L106–L114. However, the body unconditionally describes remove_dataset as popping the dataset and calling _save_locked; ownership.py:L139–L140 returns immediately when the dataset is absent, so persistence occurs only when an entry exists. The no-file return and OSError-to-RuntimeWarning handling are supported by L172–L184. This facet neither contradicts the supplied existing knowledge nor weakens an existing requirement or warning.", + "reason_stage": "independent_review", + "verdict": "fail" + }, + { + "attempts": 4, + "facet": "failure_modes", + "feature": "ascend-trace-preprocessor", + "latest_attempt_status": "invalid", + "native_trace_id": null, + "reason": "duplicate or unrequested depth facet", + "reason_stage": "extraction_or_structural_check", + "verdict": "unknown" + }, + { + "attempts": 9, + "facet": "validation", + "feature": "code-mode-branch-selector", + "latest_attempt_status": "fail", + "native_trace_id": "1791369217052-9ee74fd8b4e3", + "reason": "L231 and L392–L394 exercise ProjectGitService.create_branch/switch_branch with mocked Git and status helpers; L233–L238 and L396–L397 support the stated backend assertions. However, no supplied evidence connects those service methods to CodeBranchSelector's callbacks or establishes them as its scoped helper, so these tests do not establish validation of the requested feature. The helper_unit classification and statement that tests were not executed are appropriately limited. The proposal does not contradict existing knowledge and retains the frontend coverage gap by explicitly excluding component rendering and callback execution.", + "reason_stage": "independent_review", + "verdict": "fail" + }, + { + "attempts": 9, + "facet": "validation", + "feature": "code-mode-commit-push", + "latest_attempt_status": "unsure", + "native_trace_id": "1791369237491-fac7a72f155d", + "reason": "tests/gitPublishState.test.mjs:L5–L22 展示了三个辅助函数的具体断言,包括 0/1/3 文件文案、远程去重与空列表回退、三个错误码的中文片段、非空 Error.message 和 null fallback;CodeCommitPushControl.tsx:L6 确认组件导入这些函数,helper_unit 分类与标题相符。但提供的测试片段未展示 test/assert 的导入,无法确认所称 node:test 框架。其余描述明确限定为辅助函数测试,未宣称组件集成、实际提交推送或本批测试通过;与既有知识中组件测试用例未确认的缺口一致,也未弱化该限制。", + "reason_stage": "independent_review", + "verdict": "unsure" + }, + { + "attempts": 4, + "facet": "dependencies", + "feature": "context-usage-indicator", + "latest_attempt_reason": "duplicate or unrequested depth facet", + "latest_attempt_status": "invalid", + "native_trace_id": "1791367666694-61603bafafbf", + "reason": "ContextUsageIndicator.tsx:62–66 establishes a component without props, activeSessionId from useChatStore, and the session runtime snapshot lookup with null fallback. sessionStore.ts:935–940 establishes updating runtimes[sessionId].contextUsageSnapshot while spreading existing runtimes and runtime fields. However, lines 932–934 show only the end of an unspecified condition returning state; neither the shallow-comparison condition nor the enclosing set call is shown. Those claims therefore lack sufficient supplied evidence. The facet is consistent with existing knowledge and does not soften its rendering guards or failure warnings.", + "reason_stage": "independent_review", + "verdict": "unsure" + }, + { + "attempts": 4, + "facet": "api", + "feature": "dev-ws-traffic-logger", + "latest_attempt_reason": "duplicate or unrequested depth facet", + "latest_attempt_status": "invalid", + "native_trace_id": "1791367297550-ab5c75aedd0f", + "reason": "GET 被概括为返回 200,未保留 L369–L381 的异常分支:ENOENT 返回 200 空列表,其他读取错误返回 500 read_failed。既有 api 和 failure_modes 明确记录这一限制,拟议表述弱化了该警告。其余所述行为有据:L366–L367 默认 limit 为 300;L383–L397 处理尾部条目;L409–L439 接受空体或非 JSON 文本、脱敏后追加并在成功时返回 200;L402–L405 返回 405。", + "reason_stage": "independent_review", + "verdict": "fail" + }, + { + "attempts": 4, + "facet": "validation", + "feature": "dev-ws-traffic-logger", + "latest_attempt_status": "unknown", + "native_trace_id": null, + "reason": "提供的 vite.config.ts 片段只含插件实现,无任何测试文件、断言或文档化手动验证程序;无法给出 validation_kind 对应的真实证据。", + "reason_stage": "extraction_or_structural_check", + "verdict": "unknown" + }, + { + "attempts": 4, + "facet": "dependencies", + "feature": "dynamic-memory-cli", + "latest_attempt_status": "unsure", + "native_trace_id": "1791368050986-acf9661fcf7f", + "reason": "L49–L52 establish the missing-script exception in the shown initialization branch; L66–L71 establish command construction and UTF-8 environment overrides; L92–L100 establish JSON decoding, audit, and RuntimeError on JSONDecodeError. However, the shown lines do not connect VENDORED_SKILL to self.script, execute the subprocess with that command/environment, or establish that text comes from stdout. Those claims remain unverified by the supplied source excerpts. The facet agrees with existing gateway knowledge and does not soften its requirements or warnings.", + "reason_stage": "independent_review", + "verdict": "unsure" + }, + { + "attempts": 4, + "facet": "validation", + "feature": "frontend-incremental-lint-gate", + "latest_attempt_status": "unknown", + "native_trace_id": null, + "reason": "提供的证据仅含 lint-changed.mjs 的 L11–14 与 L36–45 两段源码,没有任何测试文件、断言或既有文档化手工验证程序;源码中的参数校验 throw 与 git show 错误分支只是被实现的防御逻辑,不构成 validation_kind 任一类别所需的验证引用行。", + "reason_stage": "extraction_or_structural_check", + "verdict": "unknown" + }, + { + "attempts": 4, + "facet": "api", + "feature": "gateway-config-hot-reload", + "latest_attempt_status": "unknown", + "native_trace_id": null, + "reason": "No offered span shows the agent.reload_config handler, _on_config_saved, or the config-save input/output contract; shown lines only cover channel_manager.get_conf_revision and the WS initial-channel-retry cancellation path (app_gateway.py:3205-3219, 3243-3252, 3299-3306), a neighboring channel-retry mechanism, so no api claim for this feature is supportable.", + "reason_stage": "extraction_or_structural_check", + "verdict": "unknown" + }, + { + "attempts": 4, + "facet": "validation", + "feature": "github-issue-feedback-script", + "latest_attempt_status": "unknown", + "native_trace_id": null, + "reason": "提供的行仅是 open_github_issue.py 的 main() 解析与创建逻辑(L18–L37、L48–L55),不含任何测试、断言或文档化的验证步骤;existing_knowledge 中关于手动执行的描述来自知识库文档而非本次 offered spans,且索引不证明测试缺失,故无可支持的验证断言。", + "reason_stage": "extraction_or_structural_check", + "verdict": "unknown" + }, + { + "attempts": 4, + "facet": "dependencies", + "feature": "huawei-maas-apikey-creation", + "latest_attempt_status": "invalid", + "native_trace_id": null, + "reason": "duplicate or unrequested depth facet", + "reason_stage": "extraction_or_structural_check", + "verdict": "unknown" + }, + { + "attempts": 4, + "facet": "flow", + "feature": "huawei-realname-account-check", + "latest_attempt_status": "fail", + "native_trace_id": "1791367931492-0beede6aea9a", + "reason": "The shown lines support the fixed 15,000ms connection timeout, 2s sleep, popup loop, 8,000ms detection call, JS/DOM decisions, timeout False, make_success, and guarded pw.stop(). However, '接管已有 page' is not established by the shown connect_page call; check_account.py:L53 is a docstring, and connect_page's implementation is not supplied. Existing dependencies knowledge explicitly records a new-page fallback when no page exists, conflicting with the unqualified existing-page description. The facet preserves the whitespace polling and timeout-to-False limitations and makes no test-execution claim.", + "reason_stage": "independent_review", + "verdict": "fail" + }, + { + "attempts": 4, + "facet": "validation", + "feature": "ide-terminal-command-mirror", + "latest_attempt_reason": "提供的两段文档(VSCode插件指南 L324-L328、JetBrains插件指南 L330-L336)仅描述终端创建/复用行为与设置开关的作用,不包含任何可执行的验证命令、操作步骤或验收预期,不足以支撑 automated_runtime、automated_source_text、helper_unit 或 documented_manual 任一类别;前次按 documented_manual 的表述已被拒绝,且本包未提供源码或测试文件。", + "latest_attempt_status": "unknown", + "native_trace_id": "1791367699338-ecb5f81324d2", + "reason": "The cited VS Code lines 326–328 and JetBrains lines 332–336 document terminal behavior and configuration, but provide no manual verification instructions or acceptance procedure. The title and body therefore overstate the evidence as documented_manual acceptance steps; the proposed steps are synthesized from behavioral descriptions. The expected behavior is consistent with existing knowledge, and the explicit statements that these steps were not executed assert no passed tests or broader test-absence guarantee. The existing gap concerning tests elsewhere in the repository remains unresolved.", + "reason_stage": "independent_review", + "verdict": "fail" + }, + { + "attempts": 4, + "facet": "dependencies", + "feature": "im-attachment-persist-hook-969909e1", + "latest_attempt_reason": "The offered spans omit the hook's upload dispatch and the enclosing function of agent_http_bridge.py:92-100, so the production coupling between the persist hook and upload_file_bytes/fetch_agent_unary cannot be established from contiguous shown lines; the test span (test_attachment_persist.py:185-195) shows only a monkeypatch setup, not the hook invocation, and e2a_proxy.py:84-91/225-264 belong to neighboring routing helpers.", + "latest_attempt_status": "unknown", + "native_trace_id": "1791367743881-fc22709e5f30", + "reason": "Test lines 185–195 show the threshold import, fake failure tuple and monkeypatch target, but no oversized payload, hook invocation or assertion establishing that the fake uploader drives the hook. The title therefore overstates the demonstrated dependency despite the body's production-dispatch caveat. Bridge lines 92–100 establish failure-tuple propagation and missing-path rejection, but do not identify the enclosing function or called uploader, so describing these as consumption of the uploader's tuple is unsupported. The facet is consistent with existing HTTP-bridge knowledge and does not soften its fail-hard or routing warnings.", + "reason_stage": "independent_review", + "verdict": "fail" + }, + { + "attempts": 4, + "facet": "validation", + "feature": "im-channel-hot-reconfig", + "latest_attempt_status": "invalid", + "native_trace_id": null, + "reason": "depth prose contains machine-specific information", + "reason_stage": "extraction_or_structural_check", + "verdict": "unknown" + }, + { + "attempts": 4, + "facet": "validation", + "feature": "locale-conf-rpc", + "latest_attempt_status": "unknown", + "native_trace_id": null, + "reason": "The offered spans contain no test or documented procedure for locale.get_conf / locale.set_conf / preferred_language: tests/unit_tests/gateway/test_app_web_handlers.py:2938-2939 uses {\"preferred_language\": \"zh\"} only as monkeypatched background for get_config_raw in test_config_set_returns_bad_request_when_team_payload_is_invalid, whose assertions (L2959-2965) target BAD_REQUEST for an invalid team payload; the other spans cover heartbeat, session.list forwarding, and the FakeWebChannel helper, none asserting locale RPC behavior.", + "reason_stage": "extraction_or_structural_check", + "verdict": "unknown" + }, + { + "attempts": 4, + "facet": "validation", + "feature": "opc-add-slide", + "latest_attempt_status": "unsure", + "native_trace_id": "1791367810642-582a42efee38", + "reason": "Pinned lines 4–5 document both commands and their expected effects: duplicating slide2 and creating a blank page on slideLayout2. These support unexecuted documented_manual checks, not automated tests or a passing result. However, the supplied evidence contains no excerpts from test_a2ui_system_flow.py or test-a2ui-action-defaults.mjs, so their asserted scope and relationship to this script cannot be verified. The proposal is consistent with existing knowledge and retains the limited gap concerning tests in the shown material without claiming repository-wide absence.", + "reason_stage": "independent_review", + "verdict": "unsure" + }, + { + "attempts": 9, + "facet": "validation", + "feature": "ppt-figure-panel-layout", + "latest_attempt_status": "fail", + "native_trace_id": "1791369180127-0a7b0cc79c8c", + "reason": "quality-gates.md L32–L41 requires clearing every qa_geometry error and forbids replacing that check with thumbnail inspection; L51–L57 supports manual readability and image-distortion checks, and L113–L123 supplies QA/rendering commands. pptxgenjs.md L102–L114 documents addFigurePanel inputs and proportional layout. These support unexecuted documented_manual acceptance steps, not feature-specific automated validation. The title's categorical claim that no panel-layout automated assertions exist is unsupported: no test evidence or bounded verified_absent certificate is supplied. The cited lines also do not explicitly instruct thumbnail inspection. The facet otherwise agrees with existing knowledge and retains the mandatory zero-error requirement.", + "reason_stage": "independent_review", + "verdict": "fail" + }, + { + "attempts": 4, + "facet": "failure_modes", + "feature": "ppt-system-diagram-renderer", + "latest_attempt_status": "invalid", + "native_trace_id": null, + "reason": "duplicate or unrequested depth facet", + "reason_stage": "extraction_or_structural_check", + "verdict": "unknown" + }, + { + "attempts": 9, + "facet": "validation", + "feature": "ppt-system-diagram-renderer", + "latest_attempt_status": "fail", + "native_trace_id": "1791369210349-2df9083944ae", + "reason": "The repository-wide claim that no renderSystemDiagram test files or named assertions exist is unsupported by the supplied excerpts; no bounded verified_absent certificate is provided. L113–L123 documents QA commands and rasterization, but does not establish the claimed single-page high-resolution human confirmation step. L114 establishes error exit code 1 for qa_geometry.py, not qa_density.py. The documented_manual classification and NOT EXECUTED qualification are appropriate for the cited deck-level checks, whose observable criteria include geometry hard errors and the density threshold. L832–L840 supports runtime overlap warnings, consistent with existing knowledge; the proposal neither contradicts nor explicitly relaxes the existing structural checks or warnings.", + "reason_stage": "independent_review", + "verdict": "fail" + }, + { + "attempts": 9, + "facet": "validation", + "feature": "rsi-experiment-ui", + "latest_attempt_status": "fail", + "native_trace_id": "1791369186446-e87e237f8020", + "reason": "StageTree L5–L26 and L41–L58 support the baseline, iteration and node-update assertions. Polling L61–L80 exercises useRsiStore.refreshDetail and asserts shared Promise identity, four calls during overlap, eight after a subsequent refresh, and RUNNING status. However, L28–L51 only bundles and imports RsiDetail; the shown test never renders or invokes it, so the title's RsiDetail polling coverage and body's component-logic validation claim are overstated. The shown lines also omit the mocks mapping and StageTree import, leaving the exact rsiApi mock boundary and real-store provenance incompletely established. automated_runtime fits the displayed store assertions, but does not establish component integration or execution in this batch. The explicit unexecuted and backend/UI limitations remain intact, and there is no conflict with existing knowledge.", + "reason_stage": "independent_review", + "verdict": "fail" + }, + { + "attempts": 4, + "facet": "validation", + "feature": "user-todos-tool", + "latest_attempt_status": "unknown", + "native_trace_id": null, + "reason": "No test asserting user_todos behavior is offered. The only shown test (tests/unit_tests/agentserver/test_code_adapter_runtime_config.py:21-67) monkeypatches user_todo_tool.set_global_workspace_dir/set_global_channel_id and stubs get_decorated_tools to return [] (lines 50-52), and its assertions (lines 64-67) cover only adapter rail behavior, never the tool itself. No docs are offered either.", + "reason_stage": "extraction_or_structural_check", + "verdict": "unknown" + }, + { + "attempts": 4, + "facet": "failure_modes", + "feature": "video-coarse-scan-frame-extraction", + "latest_attempt_status": "fail", + "native_trace_id": "1791368124396-aae0a760ccbc", + "reason": "标题将 RuntimeError 条件限定为状态缺失或 OSError/JSONDecodeError,但 L241–L245 明确在 batch_size 不匹配时也抛 RuntimeError,遗漏了该失败分支。正文关于缺失文件(L232–L235)、读取异常转换(L236–L239)、非法 UTF-8 和非对象 JSON 不被该 except 捕获的说明成立;列表会在 L241 的 state.get 调用处触发 AttributeError。与现有知识无冲突,也未弱化现有要求或警告。", + "reason_stage": "independent_review", + "verdict": "fail" + }, + { + "attempts": 4, + "facet": "failure_modes", + "feature": "workspace-git-diff", + "latest_attempt_status": "invalid", + "native_trace_id": null, + "reason": "duplicate or unrequested depth facet", + "reason_stage": "extraction_or_structural_check", + "verdict": "unknown" + }, + { + "attempts": 4, + "facet": "validation", + "feature": "workspace-git-diff", + "latest_attempt_status": "invalid", + "native_trace_id": null, + "reason": "duplicate or unrequested depth facet", + "reason_stage": "extraction_or_structural_check", + "verdict": "unknown" + }, + { + "attempts": 4, + "facet": "failure_modes", + "feature": "xiaoyi-alarm-crud", + "latest_attempt_reason": "duplicate or unrequested depth facet", + "latest_attempt_status": "invalid", + "native_trace_id": "1791367601584-9aa256d2f7f2", + "reason": "标题的 dict 限制、非 dict 直接返回及 from None 均符合 L210–L228,但正文混淆两个错误分支:code 失败时才按 errorMsg、errMsg、\"未知错误\" 的顺序取非假值;retErrCode 分支仅使用 outputs.get(\"errMsg\", \"未知错误\"),不会读取 errorMsg,且已存在的空值不会触发默认值。L224 还要求 retErrCode 非 None,不能仅表述为字段存在且字符串不为 \"0\"。L53–L55 显示 status=400,但未显示所属类;本次所示源码也未包含闹钟工具调用该共享 helper 的位置。提案与现有知识无明确冲突,也未削弱现有要求或验证证据缺口。", + "reason_stage": "independent_review", + "verdict": "fail" + }, + { + "attempts": 4, + "facet": "api", + "feature": "xiaoyi-calendar-tools", + "latest_attempt_reason": "duplicate or unrequested depth facet", + "latest_attempt_status": "invalid", + "native_trace_id": "1791367163649-9a364a3c4b43", + "reason": "L91–L95、L113–L129 支持三个必填参数、假值检查及按指定 strptime 格式解析,解析产生的 ValueError 转为 ToolInputError;L198–L202 支持 search 的 title 默认 None。但 L170–L173 仅证明包含 title/dt_start/dt_end/result 的字典被传入 format_success_response,未展示该辅助函数的实现,不能确认最终返回字典的结构。标题的格式说明可作为解析格式契约,但不能据此保证严格的固定宽度字符校验。与现有知识一致,未削弱既有要求或警告。", + "reason_stage": "independent_review", + "verdict": "unsure" + }, + { + "attempts": 4, + "facet": "tradeoffs", + "feature": "xiaoyi-location-tool", + "latest_attempt_status": "fail", + "native_trace_id": "1791368150693-6a9a3e03fd5a", + "reason": "L26 supports the zero-argument entry and L41–L54 supports hardcoded protocol fields. However, the supplied excerpts do not show the complete L26–L86 function or execute_device_command internals. L23 establishes descriptive timeout/retry instructions, not exclusive model-side enforcement. The claimed lack of code-enforced timeout/retry overstates the evidence and conflicts with existing knowledge that shared-command timeout is separately determined. Omitting the existing explicit caveat that shared-helper timeout/retry behavior is unknown weakens that limitation.", + "reason_stage": "independent_review", + "verdict": "fail" + }, + { + "attempts": 4, + "facet": "api", + "feature": "xiaoyi-pushdata-store-and-viewer", + "latest_attempt_reason": "duplicate or unrequested depth facet", + "latest_attempt_status": "invalid", + "native_trace_id": "1791366799544-4861c222671b", + "reason": "pushdata_manager.py L81–L100 supports UUID generation and return after writing. push_result_tool.py L50–L58 supports the limit formula and keyword dispatch, and L71–L92/L114–L134 supports success:true JSON for successful branches. However, the proposed return contract states success:true without restricting it to those branches; existing knowledge records an Exception branch returning success:false and error. It also drops the existing warning that negative limits are not clamped and are applied through slicing (shown at L68). Qualify the successful return contract and retain these exception and limit limitations.", + "reason_stage": "independent_review", + "verdict": "fail" + }, + { + "attempts": 9, + "facet": "validation", + "feature": "xiaoyi-save-to-phone-tools", + "latest_attempt_status": "unsure", + "native_trace_id": "1791369189424-4934a3289750", + "reason": "L1872–L1880 directly supports the existing helper test’s enabled-count and empty-config assertions; L461–L469 supports the configuration gate and use of _XIAOYI_PHONE_TOOLS. However, L144–L145 shows only the two symbol names, without the enclosing tuple definition, so their membership in _XIAOYI_PHONE_TOOLS and resulting indirect registration coverage remain unconfirmed. helper_unit accurately describes the scoped builder test. The proposal explicitly says it was not run and preserves the limitations concerning individual identities, uploads, and device interaction. Existing knowledge’s statement that its input contained no test files is scoped to that earlier input and does not contradict this evidence.", + "reason_stage": "independent_review", + "verdict": "unsure" + }, + { + "attempts": 4, + "facet": "tradeoffs", + "feature": "xlsx-reader-structural-diff", + "latest_attempt_status": "fail", + "native_trace_id": "1791368025234-d6e605a99bed", + "reason": "L81–L99 establish default sampling of 50 worksheets and 200 non-empty cells per sheet; L128–L136 compare only shared sampled sheets and old sampled refs, retaining at most 100 changes. The title’s 'can miss' is supported, but 'changes beyond those caps or on unsampled sheets go unreported' is too absolute: an old sampled ref excluded from the new sample is reported as '' (L132–L135). Existing architecture knowledge also describes a separate structural comparison, so sampling limits do not establish that all changes on unsampled sheets go unreported. The facet preserves the sampling warning and does not soften an existing requirement.", + "reason_stage": "independent_review", + "verdict": "fail" + }, + { + "attempts": 4, + "facet": "configuration", + "feature": "yuanrong-agent-file-transfer", + "latest_attempt_status": "fail", + "native_trace_id": "1791368029753-2ae48c051be0", + "reason": "Lines 924–934 establish keyword-only mkdir_agent_dir defaults mode=None and recursive=False. Test lines 1147–1168 exercise mkdir_agent_dir and assert omission of mode= and inclusion of recursive=false; they do not establish execution in this batch. Neither citation establishes download defaults offset=0/limit=65536. The title attributes those defaults to download_agent_dir, while the body names download_agent_file, so the title and body are inconsistent. The supported mkdir claims remain consistent with existing knowledge and do not soften its validation requirements or warnings.", + "reason_stage": "independent_review", + "verdict": "fail" + } + ], + "foundation": [ + { + "attempts": 4, + "facet": "architecture", + "feature": "a2x-registry-client-sdk", + "generator_trace_ids": [ + "1791370671275-f62e82f82fb6" + ], + "judge_trace_ids": [], + "last_input_sha256": "4ef39de0ff92798a34c5bfc3748580eb1161e063bfa6c5a766afdc50f8e54742", + "last_result_sha256": "22cc3c8a502fdce4df7bc80804c48e91b2d82a7202f0b095b83af1abf78fa863", + "reason": "ModelUnavailable: zcode:GLM-5.3 reply failed its schema: ValueError('a facet may appear only once')", + "reason_category": "generator_structure", + "verdict": "unknown" + }, + { + "attempts": 4, + "facet": "features", + "feature": "agent-template-layered-validation", + "generator_trace_ids": [ + "1791370691424-851ad0dd67d6" + ], + "judge_trace_ids": [ + "1791370721257-60d6b0a48c10" + ], + "last_input_sha256": "c53bc3d337e2ff9ec196f2fb960f51d63ae242af92ba9da2c1db48b4681aeaf2", + "last_result_sha256": "7102671d45ca032a522cd23c587cab440a4f440a62976ab607ebaab0621cb1a6", + "reason": "“rails[] 只检查继承 Rail 基类和无参构造”不准确:validate_template.py:L767–L770 还检查展示字段、加载声明的类并检查运行时路径策略。其余主要声明得到 L738–L761、L524–L538 及 validate_hot_load_worker.py:L57–L133、L239–L252 支持。", + "reason_category": "unsupported_assertion", + "verdict": "fail" + }, + { + "attempts": 4, + "facet": "validation", + "feature": "agentos-sandbox-create-lifecycle", + "generator_trace_ids": [ + "1791370748485-9f35e74fb4ab" + ], + "judge_trace_ids": [], + "last_input_sha256": "381d4996de5d2d2f15982b74290feb245dcfe15bf45dd778365571ff1c67ceac", + "last_result_sha256": "5f206ba3df090f0d08765e9ce7a24042cc2c011a83cf772f7007863edcfd219b", + "reason": "ModelUnavailable: zcode:GLM-5.3 reply failed its schema: ValueError('a facet may appear only once')", + "reason_category": "generator_structure", + "verdict": "unknown" + }, + { + "attempts": 4, + "facet": "tradeoffs", + "feature": "ascend-trace-analysis-pipeline", + "generator_trace_ids": [ + "1791370664540-3124e60434d9" + ], + "judge_trace_ids": [ + "1791370688816-61dcd3fc8ef7" + ], + "last_input_sha256": "9d4471a27dde1d134bd8f043678b8c8686870aefe53bf4949030c9449ab2e504", + "last_result_sha256": "e077d75006f5c6d87c376315c2f15adde9b5c1e0913510193a29341b702eaa98", + "reason": "The unconditional claim that non-ok status produces a warning is inaccurate: llm_analysis.py:L231–L237 returns disabled, while app.py:L303–L307 warns only when args.llm_analysis is enabled. The claim of independence from any LLM availability also overstates the guarantees: llm_analysis.py:L188–L208 catches FileNotFoundError and TimeoutExpired, but other subprocess launch errors can propagate before CSV/report saving at app.py:L263–L298. Union-based overlap and bubble calculations are supported by metrics.py:L460–L494 and L538–L544.", + "reason_category": "unsupported_assertion", + "verdict": "fail" + }, + { + "attempts": 4, + "facet": "tradeoffs", + "feature": "ascend-trace-compile-safety-checker", + "generator_trace_ids": [ + "1791370627257-80651e44a0ea" + ], + "judge_trace_ids": [ + "1791370657053-276b206d3652" + ], + "last_input_sha256": "c717bedb0bded2b1930a3a65aa070bbda8f162c86ed96c11050c752125ef4438", + "last_result_sha256": "a8c0c9a6b45f91bf41a25a1d964251516d9830cbf81f7aafcb1965172e64c332", + "reason": "check_compile_safety.py:L5-L16、L47-L97 支持无需编译器的文本/正则检查;L31-L44、L265、L292-L301 支持 errors/warnings 分级及 --strict 的退出行为。但“在严格性与误报噪声之间取得平衡”这一设计动机未被证据明确说明。", + "reason_category": "unsupported_assertion", + "verdict": "unsure" + }, + { + "attempts": 4, + "facet": "api", + "feature": "audit-integrity-hmac-signing", + "generator_trace_ids": [ + "1791370660633-8d908f5c820a" + ], + "judge_trace_ids": [ + "1791370689252-619205999d44" + ], + "last_input_sha256": "65497be9597e15fdc33302ff2a4a765fdafa6a04485cccec713f9b918a8c5d06", + "last_result_sha256": "e77711ac5603cbdc646a384753bd4058a403a088d0b190db802ec8bf6cb041da", + "reason": "The claim that report always returns 0 is false: audit_integrity.py:L625–L626 returns 0 only after successful report processing; L522 can raise AuditIntegrityError for missing or malformed JSON (L74–L82), which main catches and returns 1 (L709–L711). Also, not every invalid_agent_audit yields exit 1: a missing batch produces that result (L456–L458), but does not set invalid_seen (L556) or satisfy the exit-1 conditions (L627–L628).", + "reason_category": "unsupported_assertion", + "verdict": "fail" + }, + { + "attempts": 4, + "facet": "features", + "feature": "command-execution-tool", + "generator_trace_ids": [ + "1791370644519-975b7ae575c6" + ], + "judge_trace_ids": [], + "last_input_sha256": "6fbc81e91c6f595c4cc3a51981b9349626c28f361d80873ca83166b86067f772", + "last_result_sha256": "3191c6c8babe96b9d62bf029fe72d2e976a3eae9593ea2c6ce8c793413cd00f6", + "reason": "evidence outside shown input", + "reason_category": "invalid_source_reference", + "verdict": "unknown" + }, + { + "attempts": 4, + "facet": "api", + "feature": "daily-report-skill", + "generator_trace_ids": [ + "1791370705250-4c410c0611bf" + ], + "judge_trace_ids": [ + "1791370732941-791a684e993e" + ], + "last_input_sha256": "845eb5f0eee596ed4bb578d54ec56ce23747e0e452522658d6c40dd53aa160bf", + "last_result_sha256": "1b62fd72054e14d7df62d725e1e6e9f68dfeb28d5776fe8a3ef8f1dd364f316c", + "reason": "The claim that saving only prints REPORT_FILE: omits the INFO message printed to stderr for daily reports with AI enabled (run_report.py:L761–L762, L777–L790). The blanket claim that AI failures produce report comments also overstates the behavior: model invocation exceptions are swallowed and trigger fallback output (ai_analyzer.py:L187–L191, L246–L247); only exceptions reaching generate_daily_report's handler produce comments (run_report.py:L600–L603).", + "reason_category": "unsupported_assertion", + "verdict": "fail" + }, + { + "attempts": 4, + "facet": "tradeoffs", + "feature": "daily-report-skill", + "generator_trace_ids": [ + "1791370705250-4c410c0611bf" + ], + "judge_trace_ids": [ + "1791370765349-1c56f913053b" + ], + "last_input_sha256": "845eb5f0eee596ed4bb578d54ec56ce23747e0e452522658d6c40dd53aa160bf", + "last_result_sha256": "1b62fd72054e14d7df62d725e1e6e9f68dfeb28d5776fe8a3ef8f1dd364f316c", + "reason": "The implementation facts are supported: run_report.py:L764-L768 delegates weekly to daily; L391 and L501-L546 enable AI by default; report_generator.py:L113-L140 aggregates a seven-day range without analyzer calls; L420-L438 and L461-L479 contain static narrative text. However, these facts do not establish that daily compatibility or aggregation is gained by sacrificing weekly semantics or analysis. That tradeoff remains an explicitly labeled inference.", + "reason_category": "unsupported_assertion", + "verdict": "unsure" + }, + { + "attempts": 4, + "facet": "tradeoffs", + "feature": "deepsearch-research-pipeline", + "generator_trace_ids": [ + "1791370659296-f48eba725bc1" + ], + "judge_trace_ids": [ + "1791370697438-f3ce1fe035e4" + ], + "last_input_sha256": "1b8bcddb931bdbc95839323ac8e6e56002d96630bf6d835fdd71b2dc565910a2", + "last_result_sha256": "22a5ba3729ba56fa4f23581d50446fc4b64276ac7cf655667ed231cfee145073", + "reason": "main.py:L233–L290 supports argument stripping, the environment guard, detached spawning, PID.info, and parent exit; L323–L329 supports default background execution; L216 supports synchronous Agent execution. However, the exclusive claim that CLI callers can track progress only through PID.info and persisted reports/logs is not established. DEVNULL applies only to the non-Windows branch (L275–L283), and --foreground is available (L315–L325).", + "reason_category": "unsupported_assertion", + "verdict": "unsure" + }, + { + "attempts": 4, + "facet": "validation", + "feature": "deepsearch-research-pipeline", + "generator_trace_ids": [ + "1791370659296-f48eba725bc1" + ], + "judge_trace_ids": [], + "last_input_sha256": "1b8bcddb931bdbc95839323ac8e6e56002d96630bf6d835fdd71b2dc565910a2", + "last_result_sha256": "22a5ba3729ba56fa4f23581d50446fc4b64276ac7cf655667ed231cfee145073", + "reason": "knowledge:feature-deepsearch-research-pipeline:validation: scripts/main.py does not exist at openJiuwen-ai/jiuwenswarm@f0a69728c96b", + "reason_category": "invalid_source_reference", + "verdict": "unknown" + }, + { + "attempts": 4, + "facet": "configuration", + "feature": "docx-pro-cli", + "generator_trace_ids": [ + "1791370682866-1734ed8b16d5" + ], + "judge_trace_ids": [ + "1791370709103-1c403524aa33" + ], + "last_input_sha256": "09864451ab9ec0c4da6bf1a796ae3952ca6eaa144e24046114c32b9c4afb904d", + "last_result_sha256": "1c785519ac08ec4c2fdd9e56710337ce9a1ad091b45adff185529ed1a7d0c325", + "reason": "The overrides, boolean parsing and title fallback match docx_pro.py:L69–L77 and L113–L115; CLI defaults match L375–L399; module defaults match docx_replace.py:L228–L231 and renderer.py:L671–L673. However, the absolute claim that configuration uses no external configuration files or environment variables is not settled: docx_pro.py:L38–L41 imports modules whose complete configuration behavior is not supplied.", + "reason_category": "unsupported_assertion", + "verdict": "unsure" + }, + { + "attempts": 4, + "facet": "tradeoffs", + "feature": "huawei-maas-apikey-creation", + "generator_trace_ids": [ + "1791370678143-a74b5ff98e96" + ], + "judge_trace_ids": [], + "last_input_sha256": "a974aaed362f4c891aea55f1df8bc228eef312777c9d3e10a97c1b777858cf2d", + "last_result_sha256": "07f6ff2f8ba2769c9d45e1613957227aab405a3c922826c742ef32d68be71a62", + "reason": "ModelUnavailable: zcode:GLM-5.3 reply failed its schema: ValueError('a facet may appear only once')", + "reason_category": "generator_structure", + "verdict": "unknown" + }, + { + "attempts": 4, + "facet": "tradeoffs", + "feature": "ide-turn-rewind-snapshot", + "generator_trace_ids": [ + "1791370723445-47346164dd10" + ], + "judge_trace_ids": [ + "1791370755329-a3114ae17903" + ], + "last_input_sha256": "809e5b5c8837c0f83e2369ced50dd141c0dcbfe0b0db22f10ae4f65cc73b7e21", + "last_result_sha256": "9db7953f88d6aebd8c20ca0a1175b0e975e4a5afa13430e580765e978f9c0698", + "reason": "The claim that switching sessions loses snapshots overgeneralizes new_session behavior. ChatToolWindow.kt:L355-L357 clears snapshots for new_session, but switch_session at L363-L379 and onSessionChange at L569-L574 do not clear them. The whitelist, path extraction, ReadAction read, and enabled default are supported by ChatToolWindow.kt:L627-L649 and JiuwenSwarmSettings.kt:L36-L37.", + "reason_category": "unsupported_assertion", + "verdict": "fail" + }, + { + "attempts": 4, + "facet": "tradeoffs", + "feature": "im-channel-hot-reconfig", + "generator_trace_ids": [ + "1791370726969-e3fbdd335b37" + ], + "judge_trace_ids": [ + "1791370757534-c83ed88471eb" + ], + "last_input_sha256": "841eec024eb8ab5287f0a578f6c6b28755dcc75bf01682fbbf71f5d27997fe5f", + "last_result_sha256": "f309d21c47e34026989f8b4e4506055ba2f0da76bc92b1203642eb4d270d59ee", + "reason": "DingTalk teardown does not return immediately: background_wait detaches only the task cancellation wait (app_gateway.py:L2478–L2492); channel.stop() is still awaited with timeout=10.0 before unregistering (L2510–L2517, L2791). Rebuilding is also conditional: disabled or missing DingTalk configuration leaves the channel stopped (L2794–L2814), contrary to the unconditional rebuild claim.", + "reason_category": "unsupported_assertion", + "verdict": "fail" + }, + { + "attempts": 4, + "facet": "architecture", + "feature": "maas-auto-open-models", + "generator_trace_ids": [ + "1791370699268-19ed260ef48b" + ], + "judge_trace_ids": [ + "1791370728510-116fceaa3d54" + ], + "last_input_sha256": "ec6e1df20024cd8a29b3be0b967bea745953107f5440a9d07c55db34f345c01e", + "last_result_sha256": "47fafcafafff918dc7eb68e312f50d729b1f667c979f51c600240970630f7a6b", + "reason": "“各段失败均写入 per-model failed 而非中断整体流程”不符合证据:auto_open_model.py:L696–L697 的刷新失败仅记日志,L761–L762 的未预期异常直接返回 make_failure。回读验证也仅在 success 分支中针对 checked_models 执行(L686–L698),并非无条件逐模型验证。L524 仅证明调用 connect_page,未证明外部已登录态或其为脚本唯一控制面。", + "reason_category": "unsupported_assertion", + "verdict": "fail" + }, + { + "attempts": 4, + "facet": "tradeoffs", + "feature": "ppt-execution-lock-validator", + "generator_trace_ids": [ + "1791370734910-da76af1693d9" + ], + "judge_trace_ids": [ + "1791370764327-142fbaf29975" + ], + "last_input_sha256": "b8c8601b99983521e9155f3ed328ad66f757b1a8e97ec658389b21fa1b08d9b3", + "last_result_sha256": "0cc7fc2ad2b822edcbe074d61bd5072dd872db57831d6b178b45a5d2bd65e4b5", + "reason": "validate-execution-lock.js:L9 imports ./validate-evidence-plan.js, contradicting the claim of a single-file script depending only on fs/path. L191–L194 and L235–L240 implement cross-file semantic validation, contradicting the blanket claim that it cannot validate cross-file semantics. L25–L33 also restrict workspace placement, so '任意技能工作区' overstates portability.", + "reason_category": "unsupported_assertion", + "verdict": "fail" + }, + { + "attempts": 4, + "facet": "architecture", + "feature": "ppt-system-diagram-renderer", + "generator_trace_ids": [ + "1791370721196-41cf731eab5b" + ], + "judge_trace_ids": [], + "last_input_sha256": "6b5f16fc2c8a90edb3e3d4ef018da0c3465c7673df2e6a80aafe4ad6fef41a14", + "last_result_sha256": "eb9b7e6c2d1348c51a8ebf34633b4e9228a35ab49bd22b762090444691dcee2a", + "reason": "ModelUnavailable: reply is not a JSON object", + "reason_category": "generator_structure", + "verdict": "unknown" + }, + { + "attempts": 4, + "facet": "configuration", + "feature": "ppt-system-diagram-renderer", + "generator_trace_ids": [ + "1791370721196-41cf731eab5b" + ], + "judge_trace_ids": [], + "last_input_sha256": "6b5f16fc2c8a90edb3e3d4ef018da0c3465c7673df2e6a80aafe4ad6fef41a14", + "last_result_sha256": "eb9b7e6c2d1348c51a8ebf34633b4e9228a35ab49bd22b762090444691dcee2a", + "reason": "ModelUnavailable: reply is not a JSON object", + "reason_category": "generator_structure", + "verdict": "unknown" + }, + { + "attempts": 4, + "facet": "architecture", + "feature": "rsi-dataset-folder-check", + "generator_trace_ids": [ + "1791370735852-80d66c9a85e3" + ], + "judge_trace_ids": [ + "1791370767561-b834f95d5cb4" + ], + "last_input_sha256": "2c0e5afe5a08fd96141c4061df0b48649302d93a2f5cc727eb653fa18ee295ee", + "last_result_sha256": "e19f6e541164bf2e6dfbdf347dcac6644b3f940cec9b350268f99bfe2ffd3db1", + "reason": "The stated control flow is inaccurate: check_folder.py:L79–L98 checks task.json existence, keys, and cross-manifest values before enumerating seed/. Enumeration and files_in_seed/artifact_path checks (L99–L125) occur only when task.json exists, rather than unconditionally first.", + "reason_category": "unsupported_assertion", + "verdict": "fail" + }, + { + "attempts": 4, + "facet": "validation", + "feature": "share-image-export", + "generator_trace_ids": [ + "1791370756162-1a38d14e781c" + ], + "judge_trace_ids": [], + "last_input_sha256": "11c04ab30a1a5080b8c312a845fd2e4d67d862024fef926f9af8cefb9143cc24", + "last_result_sha256": "5df1e5c42d9eb99f52624cf3c9c8c469dbe0934314be4d21ba7459a1eead347b", + "reason": "ModelUnavailable: zcode:GLM-5.3 reply failed its schema: ValueError('a facet may appear only once')", + "reason_category": "generator_structure", + "verdict": "unknown" + }, + { + "attempts": 4, + "facet": "tradeoffs", + "feature": "skill-generator-cli", + "generator_trace_ids": [ + "1791370772032-b4d7a80d58bd" + ], + "judge_trace_ids": [ + "1791370808668-ab25de664a5c" + ], + "last_input_sha256": "6318b2c3854a31fb15e17960eff5e53962e62e8fa027832bd2ce18f02ceb09c1", + "last_result_sha256": "55145acc17865f4cce23768c6cbe23d0786299e6f9bb3225ac81af6b6b87e964", + "reason": "“每次只加载所需路径”超出证据:handler 内延迟导入属实(skill_generator_cli.py:L67、L82),但 url_ingest/__init__.py:L13–L16 同时导入 router、url_safety 和两个抓取后端,router.py:L15–L16 也同时导入两个后端。SSRF 包装入口被绕过的描述有支持(CLI:L81–L88;__init__.py:L34–L51)。", + "reason_category": "unsupported_assertion", + "verdict": "fail" + }, + { + "attempts": 4, + "facet": "architecture", + "feature": "video-agent-managed-task-service", + "generator_trace_ids": [ + "1791370797765-5bd12b3af76e" + ], + "judge_trace_ids": [ + "1791370830513-8570bc417cc8" + ], + "last_input_sha256": "0d2ca3bee1def42c609be39e3ee970a86427cef6363d57096c699757d66d0c02", + "last_result_sha256": "78b217aad7c6e3d4141af259c4fb2377cb3c29e64c48af6557f2b307438d260a", + "reason": "The prose misstates three conditions. service.py:L128–L135 checks independent on the candidate, not on other same-scope tasks; independent peers can still block a non-independent candidate. L86–L98 excludes settled waiting_user tasks from capacity, but does not exclude settled running/cancelling tasks. L336–L374 shows cancel schedules _cancel and notifies without calling kick; reorder persists an idempotent receipt only when command_id is provided (L413–L428, L463–L465). Thus the universal command sequence is inaccurate.", + "reason_category": "unsupported_assertion", + "verdict": "fail" + }, + { + "attempts": 4, + "facet": "api", + "feature": "video-generation-tools", + "generator_trace_ids": [ + "1791370783397-571df71ad24d" + ], + "judge_trace_ids": [ + "1791370818783-f656ccdcf019" + ], + "last_input_sha256": "83486f877ac5f54e05c766eb0f2e9dd75c7274be415ccb6ff9537fd6fb6d1e18", + "last_result_sha256": "757113f9dc2eeb0017a7440a689c1134bfb4255495ee49a91b51f0c073ad7056", + "reason": "The unconditional claim that generate_video always returns a string is false: video_gen_tools.py:L100 calls path.read_bytes() without catching OSError, and L250–L254 invokes that helper before the try block at L285. An unreadable first-frame file can therefore raise. The parameter defaults, validation order, and OpenRouter status handling are supported by L199–L207, L240–L248, L341–L349, and L366–L375.", + "reason_category": "unsupported_assertion", + "verdict": "fail" + }, + { + "attempts": 4, + "facet": "architecture", + "feature": "video-generation-tools", + "generator_trace_ids": [ + "1791370783397-571df71ad24d" + ], + "judge_trace_ids": [], + "last_input_sha256": "83486f877ac5f54e05c766eb0f2e9dd75c7274be415ccb6ff9537fd6fb6d1e18", + "last_result_sha256": "757113f9dc2eeb0017a7440a689c1134bfb4255495ee49a91b51f0c073ad7056", + "reason": "Archived source fixture placeholder was redacted, so original full-packet prompt identity could not be replayed. Remains unknown.", + "reason_category": "native_approval_binding", + "verdict": "unjudged" + }, + { + "attempts": 4, + "facet": "configuration", + "feature": "web-search-tools", + "generator_trace_ids": [ + "1791370792312-eeb7166fd378" + ], + "judge_trace_ids": [ + "1791370817137-440a68c2e0e4" + ], + "last_input_sha256": "b3721ed41b725413636a9ce891ec74296929f8d68907aeaf3bdf63e8b10b3298", + "last_result_sha256": "265a2c21066586efef7b5108242f9770f08467ff340839d03c47cff6b9305121", + "reason": "“将任意输入夹取到 1–20”过度概括:search_tools.py:L36–L39 接受 int,直接调用 min/max,并不处理任意类型输入。其余配置描述有依据:L31–L33、L43–L65、L302–L318、L372–L390、L461–L469。", + "reason_category": "unsupported_assertion", + "verdict": "fail" + }, + { + "attempts": 4, + "facet": "features", + "feature": "workspace-git-diff", + "generator_trace_ids": [ + "1791370783147-c6746521be3c" + ], + "judge_trace_ids": [ + "1791370813842-13355dfd18f0" + ], + "last_input_sha256": "28b8cd49933f16dfd9e3ced8def645fd1f9f0604cf428d442a99f4338a3ee334", + "last_result_sha256": "8ea209d5ddabc1620a9bce0ce256ead1f8c73917dbafad0e498f5ada42e0aedd", + "reason": "The claim of aggregating all changes and generating whole-file hunks for untracked files omits material limits. diff_service.py:L2127-L2154 and L2186-L2228 count untracked lines only for selected preview files; L2087-L2101 returns early for excessive tracked changes without counting untracked lines. L1914-L1930 and L1953-L1973 suppress hunks for symlinks, binary files and oversized files. Thus the unconditional wording overstates the implementation.", + "reason_category": "unsupported_assertion", + "verdict": "fail" + }, + { + "attempts": 4, + "facet": "tradeoffs", + "feature": "xiaoyi-collection-tools", + "generator_trace_ids": [ + "1791370804953-d716a11a8df3" + ], + "judge_trace_ids": [ + "1791370831157-585e108560c9" + ], + "last_input_sha256": "2464d5a235b254c5220a04e973e4fd4321b4a819982ca16cfa44833115538d8e", + "last_result_sha256": "7fc54ff052d4effc8d49d67aa8420aeeb89addb8ce0fd8bedbfa9309282ae015", + "reason": "xiaoyi_collection_tool.py:L317–L325 reads configurable upload settings, contradicting '本文件内无任何可调项'. L75–L99, L187–L213 and L342–L366 independently duplicate command dictionaries, so a shared template reducing repetition is not established. L126–L146 and L202–L204 establish unchecked list elements being forwarded, but do not establish device-side validation or that element validation was previously removed.", + "reason_category": "unsupported_assertion", + "verdict": "fail" + }, + { + "attempts": 4, + "facet": "tradeoffs", + "feature": "xiaoyi-contact-search", + "generator_trace_ids": [ + "1791370812987-3fda7826d1bc" + ], + "judge_trace_ids": [ + "1791370839513-2a587d444280" + ], + "last_input_sha256": "764570512e42feb98a69d0c54aedef7c5a9cf30a481305bfd7df74dad7f0e85f", + "last_result_sha256": "ef7c1a2f9cb8d88b59078b261133129a53dcda8d7d09756a4ec0651af47afd5c", + "reason": "contact_tools.py:L64–L73 hardcodes several parameters, but L71 sets intentParam.name dynamically from name_clean, contradicting '意图参数全部硬编码'. L84–L90 checks outputs/result types but does not normalize items; it also does not establish that stronger validation is impossible. The tradeoff claims are labeled as inference, but these factual overstatements remain.", + "reason_category": "unsupported_assertion", + "verdict": "fail" + }, + { + "attempts": 4, + "facet": "tradeoffs", + "feature": "xiaoyi-photo-gallery-tools", + "generator_trace_ids": [ + "1791370791939-12b3f57cb958" + ], + "judge_trace_ids": [ + "1791370826200-94490a250263" + ], + "last_input_sha256": "f75a4a370f0b5e830d15725dc2d8fc1e660e75ee2cbe0b08f275d632bae38305", + "last_result_sha256": "e0e4b844b419d9eba1e2425fbd201c11395e11bfc3d30e31061350b6b87b06f9", + "reason": "photo_tools.py:L36–L37、L166、L192–L195 支持缩略图优先及最多 5 条限制;L58、L170 支持描述中的 60 秒和最多重试一次;L62–L130、L173–L281 显示两个工具函数各只有一次 execute_device_command 调用。但 L97、L217 仅给出 timeOut: 5,没有说明单位、语义或与 60 秒的关系,因此无法确认“超时上限还体现在”该字段的推断;也未提供被调用函数的实现以确认底层超时和重试行为。", + "reason_category": "unsupported_assertion", + "verdict": "unsure" + }, + { + "attempts": 4, + "facet": "api", + "feature": "xiaoyi-save-to-phone-tools", + "generator_trace_ids": [ + "1791370794224-e4a23f0b0e98" + ], + "judge_trace_ids": [ + "1791370816973-9ddcfb1ecabe" + ], + "last_input_sha256": "a24218cec56b1f178c9b5253f6bb7fe35ee6ce8d8a77076a338ba88df00d69bd", + "last_result_sha256": "c6283b3dfe0946cbd7c3286283763e8fecdb48369603c4b0b95790ace6ac21ba", + "reason": "The file_name claim omits required conditions: save_tools.py:L97–L100 strips a suffix only for a truthy string whose last dot has index > 0. A truthy value such as '.env' remains unchanged, contrary to the proposed wording.", + "reason_category": "unsupported_assertion", + "verdict": "fail" + }, + { + "attempts": 4, + "facet": "validation", + "feature": "yuanrong-agent-file-transfer", + "generator_trace_ids": [ + "1791370849857-1125247313a9" + ], + "judge_trace_ids": [], + "last_input_sha256": "e44d361f8b85faee07709ef0c666e02b0f22cb5cf52af443efae78d12abe15cc", + "last_result_sha256": "ade90ff3d7962649034be729b47a3339f6e13e3d2f2ec2fa10b94c70bf0f780d", + "reason": "evidence outside shown input", + "reason_category": "invalid_source_reference", + "verdict": "unknown" + }, + { + "attempts": 4, + "facet": "validation", + "feature": "yuanrong-faas-invocation", + "generator_trace_ids": [ + "1791370827709-765e7a29765a" + ], + "judge_trace_ids": [ + "1791370852100-e0686c392747" + ], + "last_input_sha256": "f7e498708c110f20f48634aa383f74edd33f9ecaf05b2cbf345a81d567f14368", + "last_result_sha256": "ab06c96c2924b42f053eecca72f0cfdb747945d24c3e31c1f2b59d25df9ffc35", + "reason": "The claimed absent-header test is ineffective: test_yuanrong_frontend_client.py:L224 checks mixed-case \"X-session-context\" against lowercased keys, so it passes even when the header exists. The prose overstates what this test verifies. The other described assertions are supported by L192–L196, L533–L552 and L648–L659.", + "reason_category": "unsupported_assertion", + "verdict": "fail" + } + ], + "foundation_entry_binding_gaps": [ + { + "feature": "context-usage-indicator", + "reason": "六维正文齐全,但尚未满足冻结目录全部入口的源码引用要求;未计入基础说明达标功能。" + }, + { + "feature": "ide-file-edit-diff-apply", + "reason": "六维正文齐全,但尚未满足冻结目录全部入口的源码引用要求;未计入基础说明达标功能。" + } + ], + "foundation_last_attempt_categories": { + "generator_structure": 6, + "invalid_source_reference": 3, + "native_approval_binding": 1, + "unsupported_assertion": 23 + } + }, + "upstream_freshness": { + "checked_at": "2026-10-07T11:14:38.351141+00:00", + "commit_date": "2026-09-30T09:01:50Z", + "commit_gap": 0, + "pin": "f0a69728c96b5961d993449f1a901cbd2f4dac5b", + "record": { + "bytes": 225, + "path": ".kb-jiuwenswarm-finish-20261007/audit/upstream-freshness-final.json", + "sha256": "b105aaf743c12fd36620ca14b84f48acc4d5a4eded6104fa55ee430f9b0b66c2" + }, + "same_as_pin": true, + "sha": "f0a69728c96b5961d993449f1a901cbd2f4dac5b" + } +} diff --git a/eval/knowledge-depth/jiuwenswarm-init-completion-20261007.md b/eval/knowledge-depth/jiuwenswarm-init-completion-20261007.md new file mode 100644 index 00000000..a9984c4d --- /dev/null +++ b/eval/knowledge-depth/jiuwenswarm-init-completion-20261007.md @@ -0,0 +1,108 @@ +# JiuwenSwarm 初始化补齐与验收报告 + +**本轮已达到知识验收门槛:173个正式功能全部具备认可深度,七个维度分别超过90%,生产文件结构覆盖93.59%。** 基础说明从927项增至1005项,七维深度从已发布的552项增至1178项。仍有33项基础未知、33项深度未知,真实缺口继续保留。达到门槛不代表所有缺口已补齐。 + +源码固定于 `f0a69728c96b5961d993449f1a901cbd2f4dac5b`,目录固定为173项;源码审计时间 `2026-10-07T11:09:53.113528+00:00`,报告生成时间 `2026-10-07T11:27:54.963822+00:00`。核查时develop仍与该源码一致,提交差距为0;核查时间 `2026-10-07T11:14:38.351141+00:00`。这次一致性不能描述为持续实时同步。最终工具测试、CI及合并状态以本次PR记录为准。 + +功能从79扩至173后,分母从553扩大为1,211。原79功能曾达到552/553(99.82%);将相同内容放到本轮173功能目录中,才是552/1,211(45.58%)。这是范围扩大造成的统计变化。声明范围已经处理,也不代表所有潜在功能均已发现。 + +| 指标 | 补齐前已发布,按本轮目录回算 | 上次未发布预览 | 本次审计候选 | +| --- | ---: | ---: | ---: | +| 基础认可项 | 927/1,038(89.31%) | 不另计 | 1005/1,038(96.82%) | +| 基础说明达标功能(六维+入口证据) | 108/173 | 不另计 | 142/173 | +| 七维深度认可项 | 552/1,211(45.58%) | 1,047/1,211(86.46%) | 1178/1,211(97.27%) | +| 具有认可深度的功能 | 79/173 | 172/173 | 173/173 | +| 生产文件结构覆盖 | 2,058/2,199(93.59%) | 相同范围 | 2058/2199(93.59%) | +| 知识Markdown文件数 | 864 | 957 | 958 | +| 知识Markdown总字节数 | 5,346,963 | 6,321,054 | 6,803,739 | + +文件体积包含元数据、引用和证明,不能当作有效知识量或实际注入上下文量。基础六维与深度七维分别统计,不相加成覆盖率。 + +| 深度维度 | 正向认可 | 已核验缺失 | 未知 | 比例 | 门槛 | +| --- | ---: | ---: | ---: | ---: | --- | +| API 契约 | 169 | 0 | 4 | 97.69% | 通过 | +| 配置与默认行为 | 172 | 0 | 1 | 99.42% | 通过 | +| 依赖与关联功能 | 168 | 0 | 5 | 97.11% | 通过 | +| 失败与降级行为 | 168 | 0 | 5 | 97.11% | 通过 | +| 执行流程 | 172 | 0 | 1 | 99.42% | 通过 | +| 设计取舍 | 171 | 0 | 2 | 98.84% | 通过 | +| 验证与测试入口 | 158 | 0 | 15 | 91.33% | 通过 | + +每维最低为156/173;严格认可207项,轻量认可971项。所有新增认可都有固定版本的源码或项目文档引用及独立原生评审;未知不计数,没有用缺失声明补数。143/173个功能七维完整,其余30个仍有局部未知。基础六维正文齐全144个,但其中2个尚未满足全部入口源码引用,所以基础说明达标仍为142个;33个基础未知格涉及29个功能,另有这2个入口证据缺口,共31个基础未达标功能。深度证据直接引用362个生产文件,占2,199个文件的16.46%;这是直接证据范围,与93.59%的结构导航覆盖不同。 + +这轮修复了证据交接和定位:从已冻结的发现证据、旧评审及基础说明中选取对应行段,读取长文件中部、实际调用位置、嵌套测试与文档化步骤;不再把邻近代码或通用测试模板当成功能证明。GLM‑5.3负责提取,Codex独立判断忠实性、无冲突及不削弱要求;单项的失败不会停止其他功能。先核对保留的1,047项预览,再通过本轮主批次增加121项、不同证据的一轮补查增加10项,共新增131项认可;与旧已发布552项相比净增626项。 + +已有区块先保留,再只附加获认可的新内容。独立审计核对了原552项、预览1,047项及930段历史基础正文;基础原生审计另外核对1,053段历史物理区块,均完整保留。新增内容的正文哈希、源码引用和原生回复逐项绑定。 + +| 补证例子 | 新增可用上下文 | 仍明确保留的边界 | +| --- | --- | --- | +| 开发WebSocket日志 | 定位真实日志处理、文件追加与脱敏代码,避免误用旁边下载流程 | API及验证入口仍未知 | +| 小艺电话、日历、联系人等8项 | 关联实际工具构建器和27个工具开关的既有断言 | 证明工具装配/配置门控;不代表手机设备行为已验证 | +| UTC+8时间转换工具 | 关联真实工具绑定及权限轨道的allow/interrupt/denied断言 | 没有执行时间转换主体,也没有证明日期计算正确 | +| arXiv视觉提取 | 关联已有prepare→查看contact sheet→approve→used手工操作 | 属于文档化人工确认;本轮未运行,也不是裁图正确性的自动断言 | + +验证入口认可说明知道去哪里验证,并不代表测试通过。当前158项中:运行时测试52、辅助函数测试26、源码文本断言1、文档化手工流程51、历史未分类28。本轮没有执行上游项目运行时测试或这些手工流程。知识工具的测试及CI不能替代项目行为验证。 + +定向补查引入了确实不同的测试/手工步骤证据后,对16项各做一次新提取和一次独立评审,结果10项通过、4项拒绝、2项无法确认。没有自动纠错;记录明确保留历史4轮、前一证据修订4轮和新1轮,共9轮,未重置耗尽计数。6项未获认可仍保持未知。 + +| 本轮知识任务 | 原生阶段墙钟时间 | 终态 | +| --- | ---: | --- | +| foundation | 4602.62秒 | exit 0 | +| depth | 1858.02秒 | exit 0 | +| validation-evidence-revision | 257.59秒 | exit 0 | + +基础与深度阶段并行,时间不能直接相加。共用并发上限13及Zcode排期。基础确定性审计实际读取源码374次,复用已成功读取内容9849次;这说明本地读取复用,不能据此计算GLM评审速度收益。最终代码的本地源码证据复放微基准使用20个真实路径、每路径10次读取、两组各3次平衡顺序运行;完整返回哈希一致,Git子进程每轮由401次降为41次,中位耗时7.002秒降为0.722秒(下降89.69%,约9.70倍)。这是本地读取基准,零模型调用,不能当作PR评审提速。补查实际32次模型调用为16次GLM‑5.3、16次Codex;GLM实际服务模型已报告为GLM‑5.3,Codex服务端未报告实际模型身份。费用仍未知。 + +知识工具的140项整合测试、6项补查测试、26项固定源码缓存测试,以及安装后的SDK冒烟检查已通过;这些检查范围有重叠,不相加成测试总数。首次完整测试在基础知识组装期间运行,出现6处资源版本变化拒绝(3929通过、18跳过),失败记录已保留。冻结最终知识后,35项SDK相关复跑通过,完整套件正在重新运行;最终结果及CI以PR记录为准。没有为使测试通过而放宽资源版本校验。 + +这轮没有开展新的PR A/B评审实验。上下文增加可帮助评审定位入口、契约、配置和已知验证范围,但不能直接推导准确率、召回率或评审速度提升。例如,电话工具相关PR可以获得开关与装配断言;时间转换PR仍需要直接阅读转换实现及运行相应测试。模型只接收检索真正注入的内容,知识库总量不等于它收到的上下文。 + +完整输入、输出、工具调用及原生追踪保存在Git外归档。合并归档包含73个实际目录、11,959个文件、1,698,429,131字节;另外3个零任务分区从未创建追踪目录,已由终态检查点解释。历史失败、取消和未结算调用保留,不与本轮已完成终态混淆。 + +| 审计归档(相对工作区的逻辑路径,不提交原始数据) | SHA‑256 | +| --- | --- | +| `.kb-jiuwenswarm-finish-20261007/final-audit/final-acceptance/source-and-recognition-audit.json` | `fa9dff67776d8ebe8914fe81ad882e2cef252aff572cdbaed56b702f430da14e` | +| `.kb-jiuwenswarm-finish-20261007/foundation/foundation-final-audit-20261007.json` | `73f4a59ad06647229db9d388c1477e86146bd8fa9a94b4fd31e53944710822ab` | +| `.kb-jiuwenswarm-finish-20261007/foundation/foundation-unknown-33-20261007-v3.json` | `c1953d712992e6d303c0fc12b94718359ca255d22a39d18adf11945435502f5c` | +| `.kb-jiuwenswarm-finish-20261007/final-audit/native-approvals-1178.json` | `13548385cecd19fe76e37155ac864ada93bb22bf4cbcda17f89feba691bb2ad1` | +| `.kb-jiuwenswarm-finish-20261007/final-audit/final-acceptance/candidate-files-manifest.json` | `ff959e125a84271cf9513a9a9d327086dd8f22b7ba3d7c2a67e91070f502704c` | +| `.kb-jiuwenswarm-finish-20261007/final-audit/depth-native-archive-manifest.json` | `bad89a62a30fc5de4b1a7fb944269f17f39a8df3578647d3eaaef86f7a577763` | +| `.kb-jiuwenswarm-finish-20261007/foundation/cache-proposal/local-replay-benchmark-final-candidate.json` | `b245b55933e18db907162b984a626749ed714f535433fcfa13ef117c064fc861` | +| `.kb-jiuwenswarm-finish-20261007/final-audit/final-acceptance/native-archive-manifest.json` | `ff3efc1878589e9ace5d656e5847d66f5bfd2207f02af235e29f830d821b4a19` | + +剩余深度未知如下。完整基础/深度逐项原因与原生追踪标识见同名紧凑JSON;这些项目未被伪装成已核实缺失。 + +| 功能 | 未知维度 | +| --- | --- | +| `a2x-registry-client-sdk` | 依赖与关联功能 | +| `ascend-trace-preprocessor` | 失败与降级行为 | +| `code-mode-branch-selector` | 验证与测试入口 | +| `code-mode-commit-push` | 验证与测试入口 | +| `context-usage-indicator` | 依赖与关联功能 | +| `dev-ws-traffic-logger` | API 契约、验证与测试入口 | +| `dynamic-memory-cli` | 依赖与关联功能 | +| `frontend-incremental-lint-gate` | 验证与测试入口 | +| `gateway-config-hot-reload` | API 契约 | +| `github-issue-feedback-script` | 验证与测试入口 | +| `huawei-maas-apikey-creation` | 依赖与关联功能 | +| `huawei-realname-account-check` | 执行流程 | +| `ide-terminal-command-mirror` | 验证与测试入口 | +| `im-attachment-persist-hook-969909e1` | 依赖与关联功能 | +| `im-channel-hot-reconfig` | 验证与测试入口 | +| `locale-conf-rpc` | 验证与测试入口 | +| `opc-add-slide` | 验证与测试入口 | +| `ppt-figure-panel-layout` | 验证与测试入口 | +| `ppt-system-diagram-renderer` | 失败与降级行为、验证与测试入口 | +| `rsi-experiment-ui` | 验证与测试入口 | +| `user-todos-tool` | 验证与测试入口 | +| `video-coarse-scan-frame-extraction` | 失败与降级行为 | +| `workspace-git-diff` | 失败与降级行为、验证与测试入口 | +| `xiaoyi-alarm-crud` | 失败与降级行为 | +| `xiaoyi-calendar-tools` | API 契约 | +| `xiaoyi-location-tool` | 设计取舍 | +| `xiaoyi-pushdata-store-and-viewer` | API 契约 | +| `xiaoyi-save-to-phone-tools` | 验证与测试入口 | +| `xlsx-reader-structural-diff` | 设计取舍 | +| `yuanrong-agent-file-transfer` | 配置与默认行为 | + +33个基础未知按最后一次任务分类:23个说明仍不受支持(18拒绝、5无法确认)、6个生成结构错误、3个来源引用不合法、1个原生证明绑定问题。绑定问题是video-generation-tools的architecture:测试源码中的API-key示例被追踪自动脱敏,无法逐字重放固定源码的完整评审输入;原生通过回复仍未计入。这是工具/追踪证明缺口,不是源码缺失。分类使用最后一次任务,不沿用全局记录中可能残留的较早拒绝。剩余深度原因包括:说明超出了当前实现证据、测试仅覆盖邻接组件或辅助行为、通用手工指南不足以支持具体功能断言,以及无法确认接口边界。生成结构不合格、引用越出已提供范围,以及本机路径误入正文,也会留下未认可项。共享索引另保留4个二进制/文本读取问题和2个测试解析未知;它们不等于功能或测试不存在。继续补齐需要新的真实证据或更准确的声明,不能重复提交同一结论来提高比例。 diff --git a/knowledge/repos/jiuwenswarm/components/agent-runtime/_index.md b/knowledge/repos/jiuwenswarm/components/agent-runtime/_index.md index d657ab4e..42ddac3d 100644 --- a/knowledge/repos/jiuwenswarm/components/agent-runtime/_index.md +++ b/knowledge/repos/jiuwenswarm/components/agent-runtime/_index.md @@ -48,3 +48,7 @@ sources: [] - [共享 Agent 运行时(jiuwenswarm/runtime/service.py AgentRuntime)](knowledge.md) - [声明式 root Agent 定义执行(invoke_agent/stream_agent)](feature-runtime-agent-definition-execution.md) - [会话输入通道(steer/follow_up)与执行绑定 — 知识页](feature-session-input-steering.md) + +- [声明式 root Agent 定义执行(invoke_agent/stream_agent):实现深读](feature-depth-runtime-agent-definition-execution.md) + +- [Session Input Lane (steer/follow_up) and Execution Binding:实现深读](feature-depth-session-input-steering.md) diff --git a/knowledge/repos/jiuwenswarm/components/agent-runtime/feature-runtime-agent-definition-execution.md b/knowledge/repos/jiuwenswarm/components/agent-runtime/feature-runtime-agent-definition-execution.md index 7b5953df..0fc96f70 100644 --- a/knowledge/repos/jiuwenswarm/components/agent-runtime/feature-runtime-agent-definition-execution.md +++ b/knowledge/repos/jiuwenswarm/components/agent-runtime/feature-runtime-agent-definition-execution.md @@ -1,10 +1,10 @@ --- title: "声明式 root Agent 定义执行(invoke_agent/stream_agent)" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/service.py:L1258-L1308, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/agent_definition.py:L37-L64, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/agent_definition.py:L3-L8, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/service.py:L1166-L1197, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/service.py:L1209-L1234, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/service.py:L1050-L1073, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/service.py:L1209-L1256, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/agent_definition.py:L276-L286, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/agent_definition.py:L159-L166, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/agent_definition.py:L233-L247, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/agent_definition.py:L265-L271, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/agent_definition.py:L21-L34, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/agent_definition.py:L103-L135, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/agent_definition.py:L194-L203] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/service.py:L1258-L1308, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/agent_definition.py:L37-L64, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/agent_definition.py:L3-L8, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/service.py:L1166-L1197, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/service.py:L1209-L1234, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/service.py:L1050-L1073, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/service.py:L1209-L1256, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/agent_definition.py:L276-L286, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/agent_definition.py:L159-L166, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/agent_definition.py:L233-L247, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/agent_definition.py:L265-L271, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/agent_definition.py:L21-L34, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/agent_definition.py:L103-L135, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/agent_definition.py:L194-L203, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/runtime/test_agent_definition.py:L177-L183, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/runtime/test_agent_definition.py:L247-L253, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/runtime/test_agent_definition.py:L269-L274] feature: "runtime-agent-definition-execution" entry_points: ["jiuwenswarm/runtime/service.py"] source_globs: ["jiuwenswarm/runtime/service.py", "jiuwenswarm/runtime/agent_definition.py"] @@ -52,3 +52,11 @@ Sources / 来源:[jiuwenswarm/runtime/agent_definition.py:L159–L166](https:/ Sources / 来源:[jiuwenswarm/runtime/agent_definition.py:L21–L34](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/runtime/agent_definition.py#L21-L34), [jiuwenswarm/runtime/agent_definition.py:L103–L135](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/runtime/agent_definition.py#L103-L135), [jiuwenswarm/runtime/service.py:L1166–L1197](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/runtime/service.py#L1166-L1197), [jiuwenswarm/runtime/agent_definition.py:L194–L203](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/runtime/agent_definition.py#L194-L203) + + +**现有单元测试对定义校验与模式能力的覆盖** + +`tests/unit_tests/runtime/test_agent_definition.py`(标记 `pytest.mark.unit`,测试未被本分析执行)中,`test_explicit_tool_allowlist_has_stable_unsupported_error` 断言显式工具 allowlist 抛出错误码为 `AGENT_DEFINITION_TOOL_ALLOWLIST_UNSUPPORTED`、字段 `tools`、`retryable=False`;`test_work_modes_return_stable_unsupported_error` 与 `test_noncanonical_or_non_single_agent_modes_are_invalid` 分别对 `prepare_agent_execution` 断言 `AGENT_DEFINITION_MODE_UNSUPPORTED`(field=mode,不可重试)和 `AGENT_DEFINITION_MODE_INVALID`。 + +Sources / 来源:[tests/unit_tests/runtime/test_agent_definition.py:L177–L183](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/runtime/test_agent_definition.py#L177-L183), [tests/unit_tests/runtime/test_agent_definition.py:L247–L253](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/runtime/test_agent_definition.py#L247-L253), [tests/unit_tests/runtime/test_agent_definition.py:L269–L274](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/runtime/test_agent_definition.py#L269-L274) + diff --git a/knowledge/repos/jiuwenswarm/components/agent-runtime/knowledge.md b/knowledge/repos/jiuwenswarm/components/agent-runtime/knowledge.md index 3462d1fd..10df9f3a 100644 --- a/knowledge/repos/jiuwenswarm/components/agent-runtime/knowledge.md +++ b/knowledge/repos/jiuwenswarm/components/agent-runtime/knowledge.md @@ -1,10 +1,10 @@ --- title: "共享 Agent 运行时(jiuwenswarm/runtime/service.py AgentRuntime)" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/service.py:L3-L8, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/service.py:L296-L328, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/service.py:L791-L829, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/service.py:L613-L659, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:.doc_project_maintainer/modules/runtime-session/README.md:L19-L22, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/service.py:L296-L305, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/service.py:L881-L939, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/service.py:L941-L976, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/service.py:L1762-L1839, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/service.py:L307-L346, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/service.py:L486-L518, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/service.py:L204-L262, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/service.py:L547-L601] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/service.py:L3-L8, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/service.py:L296-L328, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/service.py:L791-L829, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/service.py:L613-L659, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:.doc_project_maintainer/modules/runtime-session/README.md:L19-L22, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/service.py:L296-L305, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/service.py:L881-L939, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/service.py:L941-L976, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/service.py:L1762-L1839, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/service.py:L307-L346, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/service.py:L486-L518, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/service.py:L204-L262, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/service.py:L547-L601, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/runtime/test_session_input.py:L106-L132, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/runtime/test_session_input.py:L213-L225, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/runtime/test_agent_definition.py:L288-L320] --- # 共享 Agent 运行时(jiuwenswarm/runtime/service.py AgentRuntime) @@ -41,3 +41,11 @@ Sources / 来源:[jiuwenswarm/runtime/service.py:L296–L305](https://github.c Sources / 来源:[jiuwenswarm/runtime/service.py:L307–L346](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/runtime/service.py#L307-L346), [jiuwenswarm/runtime/service.py:L486–L518](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/runtime/service.py#L486-L518), [jiuwenswarm/runtime/service.py:L204–L262](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/runtime/service.py#L204-L262), [jiuwenswarm/runtime/service.py:L547–L601](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/runtime/service.py#L547-L601) + + +**会话输入的行为单元测试与 agent_definition 的 AST 源码断言** + +tests/unit_tests/runtime/test_session_input.py 是针对 AgentRuntime 会话输入(steer 等 input_mode)的既有异步单元测试,使用可控的 GatedAgent 假 Agent:test_new_input_bypasses_busy_lane_without_answer_or_second_agent 断言原执行占用 lane 时补充输入经 invoke/stream 直接派发为 SESSION_INPUT 子执行(child.parent_execution_id 指向根执行),原执行仍 RUNNING、Agent 未被取消;test_close_cancels_inflight_input_and_cannot_reopen_session 断言 close_session 使 in-flight 的根与补充执行均以 CancelledError 结束,且关闭后再 stream 抛 RuntimeStateError。另一类是 tests/unit_tests/runtime/test_agent_definition.py 的 test_runtime_contract_has_no_execution_or_transport_dependencies:它对 agent_definition.py 源码做 AST 检查,遍历 Import/ImportFrom 语句比对模块名前缀(如 jiuwenswarm.server、websocket)并检查代码中的 ast.Name 标识符(如 AgentManager、AgentRuntime),断言违规列表为空——这是源码结构检查而非运行时行为测试。此处仅记录入口与断言内容,不代表测试曾被运行或通过。 + +Sources / 来源:[tests/unit_tests/runtime/test_session_input.py:L106–L132](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/runtime/test_session_input.py#L106-L132), [tests/unit_tests/runtime/test_session_input.py:L213–L225](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/runtime/test_session_input.py#L213-L225), [tests/unit_tests/runtime/test_agent_definition.py:L288–L320](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/runtime/test_agent_definition.py#L288-L320) + diff --git a/knowledge/repos/jiuwenswarm/components/agent-server-runtime/_index.md b/knowledge/repos/jiuwenswarm/components/agent-server-runtime/_index.md index f94c0c21..fff33dc0 100644 --- a/knowledge/repos/jiuwenswarm/components/agent-server-runtime/_index.md +++ b/knowledge/repos/jiuwenswarm/components/agent-server-runtime/_index.md @@ -58,3 +58,5 @@ sources: [] - [Skill 自演进:实现深读](feature-depth-skill-evolution.md) - [Workspace Git Diff 聚合(get_git_diff)与实时监控](feature-workspace-git-diff.md) + +- [Workspace Git Diff Aggregation (get_git_diff):实现深读](feature-depth-workspace-git-diff.md) diff --git a/knowledge/repos/jiuwenswarm/components/agents-team/_index.md b/knowledge/repos/jiuwenswarm/components/agents-team/_index.md index 7c9ea1f6..543a3cd9 100644 --- a/knowledge/repos/jiuwenswarm/components/agents-team/_index.md +++ b/knowledge/repos/jiuwenswarm/components/agents-team/_index.md @@ -89,3 +89,45 @@ sources: [] - [generate_video / check_video_status 提交后轮询的视频生成工具](feature-video-generation-tools.md) - [推送记录持久化与查询:pushdata_manager 与 view_push_result](feature-xiaoyi-pushdata-store-and-viewer.md) - [小艺保存到手机工具(save_media_to_gallery / save_file_to_file_manager)](feature-xiaoyi-save-to-phone-tools.md) + +- [A2X Registry Client SDK — mirrored sync/async service registry client:实现深读](feature-depth-a2x-registry-client-sdk.md) + +- [mcp_exec_command 跨平台命令执行工具:实现深读](feature-depth-command-execution-tool.md) + +- [Dynamic Memory CLI(SQLite UT 记忆库与发布/构建流水线):实现深读](feature-depth-dynamic-memory-cli.md) + +- [LLM Wiki 知识库(wiki_ingest/query/lint 子代理):实现深读](feature-depth-llm-wiki-knowledge-base.md) + +- [分页 PDF 文本读取工具(read_pdf):实现深读](feature-depth-pdf-reading-tool.md) + +- [DesignRail SDD 状态机(Spec-Driven Development):实现深读](feature-depth-sdd-design-rail.md) + +- [跨会话消息 Agent 工具集(SessionMessagingToolkit 六工具):实现深读](feature-depth-session-messaging-toolkit.md) + +- [user_todos Personal Per-Channel Todo Tool:实现深读](feature-depth-user-todos-tool.md) + +- [generate_video / check_video_status Submit-then-Poll Video Generation:实现深读](feature-depth-video-generation-tools.md) + +- [MCP Free/Paid Search Tools with Trusted-Search Provenance Lease:实现深读](feature-depth-web-search-tools.md) + +- [设备闹钟 CRUD 工具(create/search/modify/delete_alarm):实现深读](feature-depth-xiaoyi-alarm-crud.md) + +- [设备日历日程工具(create/search_calendar_event):实现深读](feature-depth-xiaoyi-calendar-tools.md) + +- [小艺拨打电话工具 (call_phone):实现深读](feature-depth-xiaoyi-call-phone-tool.md) + +- [小艺收藏/个人知识库工具 (query/add/delete_collection):实现深读](feature-depth-xiaoyi-collection-tools.md) + +- [设备联系人搜索工具(search_contact):实现深读](feature-depth-xiaoyi-contact-search.md) + +- [设备定位工具(get_user_location):实现深读](feature-depth-xiaoyi-location-tool.md) + +- [小艺备忘录工具 (create_note / search_notes / modify_note):实现深读](feature-depth-xiaoyi-note-tools.md) + +- [小艺图库搜索与照片上传工具 (search_photo_gallery / upload_photo):实现深读](feature-depth-xiaoyi-photo-gallery-tools.md) + +- [推送记录持久化与查询 (pushdata_manager + view_push_result):实现深读](feature-depth-xiaoyi-pushdata-store-and-viewer.md) + +- [小艺保存到手机工具 (save_media_to_gallery / save_file_to_file_manager):实现深读](feature-depth-xiaoyi-save-to-phone-tools.md) + +- [时间戳转北京时间工具 (convert_timestamp_to_utc8_time):实现深读](feature-depth-xiaoyi-timestamp-utc8-tool.md) diff --git a/knowledge/repos/jiuwenswarm/components/agents-team/feature-command-execution-tool.md b/knowledge/repos/jiuwenswarm/components/agents-team/feature-command-execution-tool.md index 6c588bec..589a11e8 100644 --- a/knowledge/repos/jiuwenswarm/components/agents-team/feature-command-execution-tool.md +++ b/knowledge/repos/jiuwenswarm/components/agents-team/feature-command-execution-tool.md @@ -1,10 +1,10 @@ --- title: "mcp_exec_command 跨平台命令执行工具" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/command_tools.py:L1129-L1145, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/command_tools.py:L881-L885, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/command_tools.py:L990-L1020, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/command_tools.py:L83-L103, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/command_tools.py:L1221-L1223] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/command_tools.py:L1129-L1145, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/command_tools.py:L881-L885, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/command_tools.py:L990-L1020, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/command_tools.py:L83-L103, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/command_tools.py:L1221-L1223, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/command_tools.py:L990-L1023, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/agents/test_command_tools_sandbox.py:L179-L192, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/command_tools.py:L69-L76, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/command_tools.py:L1086-L1106, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/command_tools.py:L1209-L1218, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/command_tools.py:L1160-L1181, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/command_execution_context.py:L24-L60, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/command_tools.py:L1146-L1158, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/command_tools.py:L871-L898, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/command_tools.py:L910-L941] feature: "command-execution-tool" entry_points: ["jiuwenswarm/agents/harness/common/tools/command_tools.py"] source_globs: ["jiuwenswarm/agents/harness/common/tools/command_tools.py", "jiuwenswarm/agents/harness/common/tools/command_execution_context.py", "jiuwenswarm/agents/harness/common/tools/command_runtime.py"] @@ -28,3 +28,29 @@ Sources / 来源:[jiuwenswarm/agents/harness/common/tools/command_tools.py:L11 Sources / 来源:[jiuwenswarm/agents/harness/common/tools/command_tools.py:L83–L103](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/command_tools.py#L83-L103), [jiuwenswarm/agents/harness/common/tools/command_tools.py:L1221–L1223](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/command_tools.py#L1221-L1223) + + +**Fail-closed sandbox vs. string-based safety analysis** + +Inference / 设计推断(非作者历史意图): + +Sandbox integrity is prioritized over availability: any sandbox config that could route to the host (`fallback_on_failure=true` or `excluded_commands`) causes an outright `[ERROR]: ... failed closed` refusal rather than attempted execution — the shown tests confirm no shell calls occur in that case. The safety layer relies on regex-based command inspection (`_check_command_safety` over `_DANGEROUS_COMMAND_PATTERNS` and PID-target analysis), which is portable across cmd/PowerShell/POSIX but inherently pattern-matching rather than a true parser; the TUI budget comment explicitly accepts false positives ("loose" `.spec.ts` pattern) as the cost of throttling. + +Sources / 来源:[jiuwenswarm/agents/harness/common/tools/command_tools.py:L990–L1023](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/command_tools.py#L990-L1023), [tests/unit_tests/agents/test_command_tools_sandbox.py:L179–L192](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/agents/test_command_tools_sandbox.py#L179-L192), [jiuwenswarm/agents/harness/common/tools/command_tools.py:L69–L76](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/command_tools.py#L69-L76) + + + +**mcp_exec_command 的公开契约** + +工具以 `@tool(name="mcp_exec_command")` 暴露,签名为 `mcp_exec_command(command, timeout_seconds=300, workdir=".", max_output_chars=0, shell_type="auto", background=False)`,描述字符串声明支持 Windows cmd/PowerShell 与 macOS/Linux bash/sh。返回值是字符串:前台成功时返回缩进 JSON(含 command/cwd/shell_type/resolved_shell/exit_code/stdout/stderr,stdout/stderr 经 `max_output_chars` 截断);`background=True` 成功时返回含 pid/status="started" 的 JSON;取消、超时与启动失败等错误路径返回 `[ERROR]: ...` 或含 `cancelled: True` 的 JSON 载荷。 + +Sources / 来源:[jiuwenswarm/agents/harness/common/tools/command_tools.py:L1086–L1106](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/command_tools.py#L1086-L1106), [jiuwenswarm/agents/harness/common/tools/command_tools.py:L1209–L1218](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/command_tools.py#L1209-L1218), [jiuwenswarm/agents/harness/common/tools/command_tools.py:L1160–L1181](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/command_tools.py#L1160-L1181) + + + +**请求局部绑定决定沙箱或宿主执行路径** + +入口在参数归一化后读取 `current_command_execution()`(基于 ContextVar 的请求局部绑定,由 `bind_command_execution(sys_operation, sandboxed=...)` 设置、`reset_command_execution(token)` 恢复):存在 sandboxed 绑定时整体交给 `_run_command_in_bound_sandbox`,先做 fail-closed 的 host-fallback 检查,再调用绑定对象的 `shell().execute_cmd/execute_cmd_background`;无绑定时走宿主路径,前台执行经 `asyncio.to_thread(_run_command_sync, ...)`——它用 0.1s 轮询循环检查超时与取消标志,仅当剥离空白后的 session_id 非空才 `register_shell_process` 注册进程以便取消,最后在 finally 中注销并关闭管道 FD。 + +Sources / 来源:[jiuwenswarm/agents/harness/common/tools/command_execution_context.py:L24–L60](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/command_execution_context.py#L24-L60), [jiuwenswarm/agents/harness/common/tools/command_tools.py:L1146–L1158](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/command_tools.py#L1146-L1158), [jiuwenswarm/agents/harness/common/tools/command_tools.py:L871–L898](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/command_tools.py#L871-L898), [jiuwenswarm/agents/harness/common/tools/command_tools.py:L910–L941](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/command_tools.py#L910-L941) + diff --git a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-calendar-tools.md b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-calendar-tools.md index 020d8089..19aa11d8 100644 --- a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-calendar-tools.md +++ b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-calendar-tools.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L113-L129, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L137-L164, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L166-L173, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L137-L160, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L244-L256, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L219-L229, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L265-L267, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L198-L207, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L210-L228, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L121-L125, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L72-L79, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L19-L24, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L163-L167, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L264-L267] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L113-L129, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L137-L164, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L166-L173, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L137-L160, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L244-L256, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L219-L229, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L265-L267, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L198-L207, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L210-L228, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L121-L125, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L72-L79, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L19-L24, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L163-L167, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L264-L267, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/agents/swarm/test_swarm_assembly.py:L1872-L1880, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/swarm/providers/tools.py:L121-L150, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/swarm/providers/tools.py:L461-L469] feature: "xiaoyi-calendar-tools" entry_points: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py"] source_globs: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py"] @@ -60,3 +60,12 @@ search 中 start_time/end_time 缺失或 _parse_time_string_ymd_hhmmss 抛 Value + + +**既有装配测试仅覆盖配置开关门控(helper 级,未执行)** +tests/agents/swarm/test_swarm_assembly.py 的 test_xiaoyi_phone_tools_gated_by_config 实际调用 _build_xiaoyi_phone_tools:config 含 channels.xiaoyi.phone_tools_enabled=True 时断言返回 27 个工具,config 为空时断言返回 []。生产元组 _XIAOYI_PHONE_TOOLS 明确包含 create_calendar_event 与 search_calendar_event,故两工具的注册随该开关被此测试间接覆盖;但断言只检查聚合计数与空列表,不校验单工具身份、意图构造或设备执行结果。validation_kind 为 helper_unit:断言只覆盖构建 helper 本身。标注:本条为对既有测试的静态审读,测试未在本次执行。 + +来源:[tests/agents/swarm/test_swarm_assembly.py:L1872–L1880](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/agents/swarm/test_swarm_assembly.py#L1872-L1880), [jiuwenswarm/agents/swarm/providers/tools.py:L121–L150](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/swarm/providers/tools.py#L121-L150), [jiuwenswarm/agents/swarm/providers/tools.py:L461–L469](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/swarm/providers/tools.py#L461-L469) + + + diff --git a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-call-phone-tool.md b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-call-phone-tool.md index a323ef64..41083eea 100644 --- a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-call-phone-tool.md +++ b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-call-phone-tool.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L45-L107, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L24-L44, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L98-L107, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L46-L61, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L70-L82, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L14-L21, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L91-L96, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L171-L207, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L109-L113, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L53-L61, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L91-L98, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L46-L55] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L45-L107, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L24-L44, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L98-L107, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L46-L61, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L70-L82, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L14-L21, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L91-L96, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L171-L207, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L109-L113, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L53-L61, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py:L91-L98, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L46-L55, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/agents/swarm/test_swarm_assembly.py:L1872-L1880, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/swarm/providers/tools.py:L121-L150, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/swarm/providers/tools.py:L461-L469] feature: "xiaoyi-call-phone-tool" entry_points: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py"] source_globs: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/phone_tools.py"] @@ -69,3 +69,14 @@ phone_number 为空/非字符串、strip 后为空或 slot_id 不在 (0,1) 时 + + +**配置门控构建 helper 的既有单测(helper 覆盖,未执行)** +设计推断(非作者历史意图): + +tests/agents/swarm/test_swarm_assembly.py 的 test_xiaoyi_phone_tools_gated_by_config 调用 tools._build_xiaoyi_phone_tools:config 为 {"channels":{"xiaoyi":{"phone_tools_enabled":True}}} 时断言返回 27 个工具,config 为 {} 时断言返回空列表。生产侧 _XIAOYI_PHONE_TOOLS 元组显式包含 call_phone,_build_xiaoyi_phone_tools 在开关关闭时返回 [](默认 False)。该断言只覆盖聚合门控 helper,不校验单个工具身份、入参校验或设备调用行为。NOT EXECUTED:此处仅引用既有测试代码,未在本次运行。推断(inference):call_phone 仅经由元组成员关系与计数 27 间接被覆盖。 + +来源:[tests/agents/swarm/test_swarm_assembly.py:L1872–L1880](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/agents/swarm/test_swarm_assembly.py#L1872-L1880), [jiuwenswarm/agents/swarm/providers/tools.py:L121–L150](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/swarm/providers/tools.py#L121-L150), [jiuwenswarm/agents/swarm/providers/tools.py:L461–L469](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/swarm/providers/tools.py#L461-L469) + + + diff --git a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-collection-tools.md b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-collection-tools.md index aeb05586..97c0d5f6 100644 --- a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-collection-tools.md +++ b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-collection-tools.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L293-L373, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L377-L384, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L165-L231, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L126-L146, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L217-L237, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L293-L303, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L386-L390, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L215-L231, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L310-L330, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L19-L24, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L215-L220, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L313-L330] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L293-L373, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L377-L384, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L165-L231, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L126-L146, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L217-L237, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L293-L303, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L386-L390, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L215-L231, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L310-L330, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L19-L24, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L215-L220, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py:L313-L330, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/agents/swarm/test_swarm_assembly.py:L1872-L1880, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/swarm/providers/tools.py:L141-L143, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/swarm/providers/tools.py:L461-L469] feature: "xiaoyi-collection-tools" entry_points: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py"] source_globs: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/xiaoyi_collection_tool.py"] @@ -69,3 +69,12 @@ delete_collection/add_collection 中 ToolInputError 被原样 re-raise(如 ite + + +**既有 swarm 装配测试覆盖配置门控下的构建数量,未覆盖工具行为** +既有测试 test_xiaoyi_phone_tools_gated_by_config 执行实际的 _build_xiaoyi_phone_tools:channels.xiaoyi.phone_tools_enabled 为 True 时断言返回 27 个工具,config 为空(默认 False)时断言返回空列表。生产元组 _XIAOYI_PHONE_TOOLS 显式包含 query_collection、add_collection、delete_collection。该断言只验证聚合数量与门控默认值,不校验单个工具身份、intent 组装或设备结果;属配置门控辅助函数级别的 helper 单元验证。本次 NOT EXECUTED,未运行该测试。 + +来源:[tests/agents/swarm/test_swarm_assembly.py:L1872–L1880](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/agents/swarm/test_swarm_assembly.py#L1872-L1880), [jiuwenswarm/agents/swarm/providers/tools.py:L141–L143](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/swarm/providers/tools.py#L141-L143), [jiuwenswarm/agents/swarm/providers/tools.py:L461–L469](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/swarm/providers/tools.py#L461-L469) + + + diff --git a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-contact-search.md b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-contact-search.md index 7060a75f..4c442b18 100644 --- a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-contact-search.md +++ b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-contact-search.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/contact_tools.py:L45-L96, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/contact_tools.py:L28-L47, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/contact_tools.py:L93-L102, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L76-L85, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/contact_tools.py:L18-L25, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/contact_tools.py:L56-L82, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L58-L62, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L87-L96, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/contact_tools.py:L45-L49, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/contact_tools.py:L98-L102, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L80-L85, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/contact_tools.py:L45-L47, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L53-L55] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/contact_tools.py:L45-L96, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/contact_tools.py:L28-L47, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/contact_tools.py:L93-L102, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L76-L85, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/contact_tools.py:L18-L25, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/contact_tools.py:L56-L82, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L58-L62, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L87-L96, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/contact_tools.py:L45-L49, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/contact_tools.py:L98-L102, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L80-L85, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/contact_tools.py:L45-L47, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L53-L55, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/agents/swarm/test_swarm_assembly.py:L1872-L1880, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/swarm/providers/tools.py:L121-L150, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/swarm/providers/tools.py:L461-L469] feature: "xiaoyi-contact-search" entry_points: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/contact_tools.py"] source_globs: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/contact_tools.py"] @@ -67,3 +67,12 @@ search_contact 对空白 name 抛出 status=400 的 ToolInputError 并原样上 + + +**既有 assembly 测试断言 phone_tools_enabled 开关下工具数量为 27 或 0(未执行)** +tests/agents/swarm/test_swarm_assembly.py:1872 的 test_xiaoyi_phone_tools_gated_by_config 实际调用 tools._build_xiaoyi_phone_tools:config 含 channels.xiaoyi.phone_tools_enabled=True 时断言返回 27 个工具,config 为空(默认 False,tools.py:464-468)时断言返回 []。生产元组 _XIAOYI_PHONE_TOOLS 显式含 search_contact(tools.py:129),故该开关覆盖其暴露;但断言仅为聚合计数,不校验 search_contact 的检索行为或设备交互。NOT EXECUTED。 + +来源:[tests/agents/swarm/test_swarm_assembly.py:L1872–L1880](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/agents/swarm/test_swarm_assembly.py#L1872-L1880), [jiuwenswarm/agents/swarm/providers/tools.py:L121–L150](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/swarm/providers/tools.py#L121-L150), [jiuwenswarm/agents/swarm/providers/tools.py:L461–L469](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/swarm/providers/tools.py#L461-L469) + + + diff --git a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-location-tool.md b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-location-tool.md index 283ec483..91abbfbb 100644 --- a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-location-tool.md +++ b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-location-tool.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py:L33-L86, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py:L34-L68, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L168-L207, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py:L16-L16, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py:L19-L31, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py:L68-L86, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py:L68-L73, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L215-L228] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py:L33-L86, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py:L34-L68, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L168-L207, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py:L16-L16, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py:L19-L31, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py:L68-L86, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py:L68-L73, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L215-L228, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/agents/swarm/test_swarm_assembly.py:L1872-L1880, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/swarm/providers/tools.py:L461-L469, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/swarm/providers/tools.py:L121-L150] feature: "xiaoyi-location-tool" entry_points: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py"] source_globs: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py"] @@ -58,3 +58,12 @@ L70–L73 将非 dict 的 outputs 包成 {"value": outputs} 后调用 raise_if_d + + +**装配测试断言 27 个工具与空列表,get_user_location 位于生产元组** +test_swarm_assembly.py:1872 的测试实际调用 _build_xiaoyi_phone_tools,断言 channels.xiaoyi.phone_tools_enabled 为 True 时返回 27 个工具、配置为空时返回 []。生产元组 _XIAOYI_PHONE_TOOLS 显式包含 get_user_location。该断言仅覆盖配置门控辅助函数与聚合数量,不涉及 get_user_location 的运行时行为;本条为已有测试证据,本次未执行。 + +来源:[tests/agents/swarm/test_swarm_assembly.py:L1872–L1880](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/agents/swarm/test_swarm_assembly.py#L1872-L1880), [jiuwenswarm/agents/swarm/providers/tools.py:L461–L469](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/swarm/providers/tools.py#L461-L469), [jiuwenswarm/agents/swarm/providers/tools.py:L121–L150](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/swarm/providers/tools.py#L121-L150) + + + diff --git a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-note-tools.md b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-note-tools.md index 510ea067..ba77311f 100644 --- a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-note-tools.md +++ b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-note-tools.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py:L107-L173, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py:L176-L204, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py:L35-L51, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py:L53-L80, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py:L211-L233, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py:L93-L97, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L210-L228, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L46-L55, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py:L15-L23, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py:L82-L87, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L80-L104, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L184-L196] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py:L107-L173, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py:L176-L204, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py:L35-L51, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py:L53-L80, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py:L211-L233, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py:L93-L97, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L210-L228, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L46-L55, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py:L15-L23, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py:L82-L87, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L80-L104, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L184-L196, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/agents/swarm/test_swarm_assembly.py:L1872-L1880, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/swarm/providers/tools.py:L121-L150, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/swarm/providers/tools.py:L461-L469] feature: "xiaoyi-note-tools" entry_points: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py"] source_globs: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/note_tools.py"] @@ -69,3 +69,12 @@ execute_device_command 在 error_result 非空时先抛出,随后用 `{} if re + + +**assembly 测试断言 27 个工具(含三个备忘录工具)仅在 phone_tools_enabled 开启时构建** +tests/agents/swarm/test_swarm_assembly.py:1872 的 test_xiaoyi_phone_tools_gated_by_config 调用实际构建器 _build_xiaoyi_phone_tools,断言 channels.xiaoyi.phone_tools_enabled=True 时返回 27 个工具、config 为空时返回 []。生产元组 _XIAOYI_PHONE_TOOLS 显式包含 create_note/search_notes/modify_note。测试只断言聚合数量与门控,不校验单个工具身份或设备侧行为;本条为已有测试条目,此处未执行。 + +来源:[tests/agents/swarm/test_swarm_assembly.py:L1872–L1880](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/agents/swarm/test_swarm_assembly.py#L1872-L1880), [jiuwenswarm/agents/swarm/providers/tools.py:L121–L150](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/swarm/providers/tools.py#L121-L150), [jiuwenswarm/agents/swarm/providers/tools.py:L461–L469](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/swarm/providers/tools.py#L461-L469) + + + diff --git a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-photo-gallery-tools.md b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-photo-gallery-tools.md index f520efe8..6d93b6b4 100644 --- a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-photo-gallery-tools.md +++ b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-photo-gallery-tools.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L133-L151, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L192-L195, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L62-L130, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L88-L109, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L208-L229, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L58-L68, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L79-L97, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L111-L116, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L173-L229, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L234-L275, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L154-L156, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L189-L199, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L277-L281] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L133-L151, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L192-L195, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L62-L130, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L88-L109, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L208-L229, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L58-L68, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L79-L97, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L111-L116, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L173-L229, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L234-L275, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L154-L156, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L189-L199, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py:L277-L281, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/agents/swarm/test_swarm_assembly.py:L1872-L1880, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/swarm/providers/tools.py:L121-L150, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/swarm/providers/tools.py:L461-L469] feature: "xiaoyi-photo-gallery-tools" entry_points: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py"] source_globs: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/photo_tools.py"] @@ -69,3 +69,12 @@ media_uris 为 None、非法 JSON 字符串、解析后非数组或类型不符 + + +**Swarm 组装测试在运行时执行 _build_xiaoyi_phone_tools 并断言开启时 27 个工具、关闭时为空** +现有测试 test_xiaoyi_phone_tools_gated_by_config 实际调用 tools._build_xiaoyi_phone_tools:config 含 channels.xiaoyi.phone_tools_enabled=True 时断言返回 27 个工具,config={}(默认 False)时断言返回 []。生产元组 _XIAOYI_PHONE_TOOLS 显式包含 search_photo_gallery 与 upload_photo,故两图库工具在该门控构建范围内;但断言仅针对聚合计数与空列表,不校验单个工具身份、传输行为或设备结果。测试在本会话中未执行。 + +来源:[tests/agents/swarm/test_swarm_assembly.py:L1872–L1880](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/agents/swarm/test_swarm_assembly.py#L1872-L1880), [jiuwenswarm/agents/swarm/providers/tools.py:L121–L150](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/swarm/providers/tools.py#L121-L150), [jiuwenswarm/agents/swarm/providers/tools.py:L461–L469](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/swarm/providers/tools.py#L461-L469) + + + diff --git a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-pushdata-store-and-viewer.md b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-pushdata-store-and-viewer.md index c3368203..f5e89c83 100644 --- a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-pushdata-store-and-viewer.md +++ b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-pushdata-store-and-viewer.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/pushdata_manager.py:L34-L51, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/pushdata_manager.py:L67-L69, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/push_result_tool.py:L136-L152, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/push_result_tool.py:L49-L69, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/push_result_tool.py:L94-L134, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/pushdata_manager.py:L18-L19, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/pushdata_manager.py:L54-L66, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/push_result_tool.py:L49-L51, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/pushdata_manager.py:L56-L66, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/pushdata_manager.py:L49-L51, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/push_result_tool.py:L14-L18, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/push_result_tool.py:L49-L62, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/pushdata_manager.py:L112-L141] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/pushdata_manager.py:L34-L51, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/pushdata_manager.py:L67-L69, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/push_result_tool.py:L136-L152, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/push_result_tool.py:L49-L69, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/push_result_tool.py:L94-L134, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/pushdata_manager.py:L18-L19, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/pushdata_manager.py:L54-L66, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/push_result_tool.py:L49-L51, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/pushdata_manager.py:L56-L66, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/pushdata_manager.py:L49-L51, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/push_result_tool.py:L14-L18, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/push_result_tool.py:L49-L62, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/pushdata_manager.py:L112-L141, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/agents/swarm/test_swarm_assembly.py:L1872-L1880, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/swarm/providers/tools.py:L121-L150, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/swarm/providers/tools.py:L461-L469] feature: "xiaoyi-pushdata-store-and-viewer" entry_points: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/push_result_tool.py", "jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/pushdata_manager.py"] source_globs: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/push_result_tool.py", "jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/pushdata_manager.py"] @@ -60,3 +60,12 @@ push_result_tool.py L18 `from .pushdata_manager import search_push_data, get_all + + +**既有 swarm 装配测试运行 _build_xiaoyi_phone_tools 并断言开关两态的工具数量(helper 单元级)** +tests/agents/swarm/test_swarm_assembly.py 的 test_xiaoyi_phone_tools_gated_by_config 实际调用 tools._build_xiaoyi_phone_tools:config 为 {"channels":{"xiaoyi":{"phone_tools_enabled":True}}} 时断言返回 27 个工具,空 config 时断言返回 []。生产元组 _XIAOYI_PHONE_TOOLS 显式包含 view_push_result,故该测试覆盖查看工具经配置开关暴露的装配路径;断言仅为聚合计数,不校验单个工具身份,pushdata_manager 存储侧不在该测试内。该验证属 helper 单元级,且本次未执行。 + +来源:[tests/agents/swarm/test_swarm_assembly.py:L1872–L1880](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/agents/swarm/test_swarm_assembly.py#L1872-L1880), [jiuwenswarm/agents/swarm/providers/tools.py:L121–L150](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/swarm/providers/tools.py#L121-L150), [jiuwenswarm/agents/swarm/providers/tools.py:L461–L469](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/swarm/providers/tools.py#L461-L469) + + + diff --git a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-timestamp-utc8-tool.md b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-timestamp-utc8-tool.md index 3ade7a72..8cb5fdd7 100644 --- a/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-timestamp-utc8-tool.md +++ b/knowledge/repos/jiuwenswarm/components/agents-team/feature-depth-xiaoyi-timestamp-utc8-tool.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/timestamp_tool.py:L49-L69, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/timestamp_tool.py:L77-L84, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/timestamp_tool.py:L19-L38, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/timestamp_tool.py:L49-L60, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/timestamp_tool.py:L13-L16, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/timestamp_tool.py:L69-L75, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/timestamp_tool.py:L39-L47, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/timestamp_tool.py:L64-L67, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L46-L55, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/timestamp_tool.py:L50-L69] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/timestamp_tool.py:L49-L69, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/timestamp_tool.py:L77-L84, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/timestamp_tool.py:L19-L38, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/timestamp_tool.py:L49-L60, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/timestamp_tool.py:L13-L16, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/timestamp_tool.py:L69-L75, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/timestamp_tool.py:L39-L47, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/timestamp_tool.py:L64-L67, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L46-L55, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/timestamp_tool.py:L50-L69, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/agentserver/permissions/test_auto_permission_pipeline.py:L722-L754, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/agentserver/permissions/test_auto_permission_pipeline.py:L757-L798, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/rails/permissions/_auto_permission/readonly_tool_bindings.py:L61-L70] feature: "xiaoyi-timestamp-utc8-tool" entry_points: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/timestamp_tool.py"] source_globs: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/timestamp_tool.py"] @@ -69,3 +69,12 @@ L39–L47 三条守卫各自抛 ToolInputError;L64–L67 的 try 仅包住 L65 + + +**Runtime permission tests bind the real convert_timestamp_to_utc8_time and assert allow/interrupt/denied outcomes; the UTC+8 conversion body is not invoked or asserted** +test_readonly_real_binding_fast_path (pytest parametrized, async) registers the actual tool card (line 751 binds bindings.convert_timestamp_to_utc8_time, line 767 forces stateless=True only for this name) and asserts per variant: expected == "allow" for valid and cross_session-with-convert_ (line 787), "denied" for deny/session_deny (line 789), via classify_permission_result(result) or AbortError→"interrupt" (lines 791-795). Args are {"timestamp": 1700000000} (line 728) but no assertion checks the returned date; guards in timestamp_tool.py L39-47 are untested here. NOT EXECUTED by this review. + +来源:[tests/unit_tests/agentserver/permissions/test_auto_permission_pipeline.py:L722–L754](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/agentserver/permissions/test_auto_permission_pipeline.py#L722-L754), [tests/unit_tests/agentserver/permissions/test_auto_permission_pipeline.py:L757–L798](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/agentserver/permissions/test_auto_permission_pipeline.py#L757-L798), [jiuwenswarm/agents/harness/common/rails/permissions/_auto_permission/readonly_tool_bindings.py:L61–L70](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/rails/permissions/_auto_permission/readonly_tool_bindings.py#L61-L70) + + + diff --git a/knowledge/repos/jiuwenswarm/components/agents-team/feature-dynamic-memory-cli.md b/knowledge/repos/jiuwenswarm/components/agents-team/feature-dynamic-memory-cli.md index 5e5cd2f1..514adcac 100644 --- a/knowledge/repos/jiuwenswarm/components/agents-team/feature-dynamic-memory-cli.md +++ b/knowledge/repos/jiuwenswarm/components/agents-team/feature-dynamic-memory-cli.md @@ -1,10 +1,10 @@ --- title: "Dynamic Memory CLI:SQLite UT 记忆库与发布/构建流水线" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/dynamic-memory-cli/scripts/dynamic_memory_cli.py:L405-L424, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/dynamic-memory-cli/scripts/dynamic_memory_cli.py:L380-L402, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/dynamic-memory-cli/scripts/dynamic_memory_cli.py:L469-L486, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/dynamic-memory-cli/scripts/dynamic_memory_cli.py:L506-L539, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/dynamic-memory-cli/scripts/dynamic_memory_cli.py:L578-L582, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/rails/eternal_conversation/memory_cli.py:L55-L69, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/dynamic-memory-cli/scripts/dynamic_memory_cli.py:L59-L95, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/dynamic-memory-cli/scripts/dynamic_memory_cli.py:L286-L318, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/rails/eternal_conversation/memory_cli.py:L89-L107, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/dynamic-memory-cli/scripts/dynamic_memory_cli.py:L506-L545, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/dynamic-memory-cli/scripts/dynamic_memory_cli.py:L86-L95, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/dynamic-memory-cli/scripts/dynamic_memory_cli.py:L311-L315, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/dynamic-memory-cli/scripts/dynamic_memory_cli.py:L218-L244, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/dynamic-memory-cli/scripts/dynamic_memory_cli.py:L321-L339, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/dynamic-memory-cli/scripts/dynamic_memory_cli.py:L342-L402] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/dynamic-memory-cli/scripts/dynamic_memory_cli.py:L405-L424, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/dynamic-memory-cli/scripts/dynamic_memory_cli.py:L380-L402, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/dynamic-memory-cli/scripts/dynamic_memory_cli.py:L469-L486, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/dynamic-memory-cli/scripts/dynamic_memory_cli.py:L506-L539, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/dynamic-memory-cli/scripts/dynamic_memory_cli.py:L578-L582, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/rails/eternal_conversation/memory_cli.py:L55-L69, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/dynamic-memory-cli/scripts/dynamic_memory_cli.py:L59-L95, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/dynamic-memory-cli/scripts/dynamic_memory_cli.py:L286-L318, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/rails/eternal_conversation/memory_cli.py:L89-L107, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/dynamic-memory-cli/scripts/dynamic_memory_cli.py:L506-L545, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/dynamic-memory-cli/scripts/dynamic_memory_cli.py:L86-L95, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/dynamic-memory-cli/scripts/dynamic_memory_cli.py:L311-L315, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/dynamic-memory-cli/scripts/dynamic_memory_cli.py:L218-L244, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/dynamic-memory-cli/scripts/dynamic_memory_cli.py:L321-L339, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/dynamic-memory-cli/scripts/dynamic_memory_cli.py:L342-L402, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/rails/eternal_conversation/memory_cli.py:L64-L107] feature: "dynamic-memory-cli" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/dynamic-memory-cli/scripts/dynamic_memory_cli.py"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/dynamic-memory-cli/scripts/dynamic_memory_cli.py", "jiuwenswarm/agents/harness/common/rails/eternal_conversation/memory_cli.py"] @@ -52,3 +52,11 @@ search 对 active UT 检索:pending UT 用内容/queries/must_include/tags/sou Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/dynamic-memory-cli/scripts/dynamic_memory_cli.py:L218–L244](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/dynamic-memory-cli/scripts/dynamic_memory_cli.py#L218-L244), [jiuwenswarm/resources/agent/workspace/skills/dynamic-memory-cli/scripts/dynamic_memory_cli.py:L321–L339](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/dynamic-memory-cli/scripts/dynamic_memory_cli.py#L321-L339), [jiuwenswarm/resources/agent/workspace/skills/dynamic-memory-cli/scripts/dynamic_memory_cli.py:L342–L402](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/dynamic-memory-cli/scripts/dynamic_memory_cli.py#L342-L402) + + +**子进程隔离与事务化验收的取舍** + +网关把每次 CLI 调用放在独立子进程并以 JSON stdout 通信,换取进程隔离与可审计性,但每次调用都要付出进程启动成本;审计写入发生在 communicate() 正常返回之后(记录参数、返回码、耗时与结果),取消路径会先终止子进程并直接重抛 CancelledError,因此该次调用不会留下审计记录。构建侧 build_pending 选择单事务全有或全无:任一 UT 的检索验收或 must_include 检查失败即整体回滚返回 failed,content_hash 与冻结批次不一致的条目被跳过而非报错,以跳过换取幂等重放。 + +Sources / 来源:[jiuwenswarm/agents/harness/common/rails/eternal_conversation/memory_cli.py:L64–L107](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/rails/eternal_conversation/memory_cli.py#L64-L107), [jiuwenswarm/resources/agent/workspace/skills/dynamic-memory-cli/scripts/dynamic_memory_cli.py:L342–L402](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/dynamic-memory-cli/scripts/dynamic_memory_cli.py#L342-L402) + diff --git a/knowledge/repos/jiuwenswarm/components/agents-team/feature-llm-wiki-knowledge-base.md b/knowledge/repos/jiuwenswarm/components/agents-team/feature-llm-wiki-knowledge-base.md index f2024993..896530f7 100644 --- a/knowledge/repos/jiuwenswarm/components/agents-team/feature-llm-wiki-knowledge-base.md +++ b/knowledge/repos/jiuwenswarm/components/agents-team/feature-llm-wiki-knowledge-base.md @@ -1,10 +1,10 @@ --- title: "LLM Wiki 知识库(wiki_ingest/query/lint 子代理)" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L195-L233, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L242-L258, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L318-L347, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L368-L415, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L470-L485, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/agents/test_wiki_tools_runtime_config.py:L30-L74, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/agents/test_wiki_tools_runtime_config.py:L77-L94, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/agents/test_wiki_tools_runtime_config.py:L97-L125] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L195-L233, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L242-L258, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L318-L347, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L368-L415, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L470-L485, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/agents/test_wiki_tools_runtime_config.py:L30-L74, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/agents/test_wiki_tools_runtime_config.py:L77-L94, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/agents/test_wiki_tools_runtime_config.py:L97-L125, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L313-L347, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L494-L519, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L470-L475, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L530-L543, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L567-L576, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L491-L521, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L494-L505, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L356-L365] feature: "llm-wiki-knowledge-base" entry_points: ["jiuwenswarm/agents/harness/common/tools/wiki_tools.py"] source_globs: ["jiuwenswarm/agents/harness/common/tools/wiki_tools.py"] @@ -36,3 +36,29 @@ tests/unit_tests/agents/test_wiki_tools_runtime_config.py 有三个用例:test Sources / 来源:[tests/unit_tests/agents/test_wiki_tools_runtime_config.py:L30–L74](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/agents/test_wiki_tools_runtime_config.py#L30-L74), [tests/unit_tests/agents/test_wiki_tools_runtime_config.py:L77–L94](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/agents/test_wiki_tools_runtime_config.py#L77-L94), [tests/unit_tests/agents/test_wiki_tools_runtime_config.py:L97–L125](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/agents/test_wiki_tools_runtime_config.py#L97-L125) + + +**SHA-256 去重导入与目录级递归收集** + +LLMWiki.ingest 计算源文件 SHA-256,force=False 且 manifest 已知该哈希时返回 skipped 而不调用 agent;成功路径把源文件复制为 sources/{sha256前8位}_{文件名} 并仅在结果无 error 时写入 manifest 记录。wiki_ingest 对目录输入递归收集 .pdf/.md/.txt 三类文件,并用 posix 路径前缀比对 .llm_wiki 工作区根来跳过自身目录,避免循环导入;每个文件的结果聚合为 [Failed]/[Skipped]: Deduplicated/[Success] 的 JSON 摘要。 + +Sources / 来源:[jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L313–L347](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/wiki_tools.py#L313-L347), [jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L494–L519](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/wiki_tools.py#L494-L519) + + + +**三个 @tool 入口的签名与错误契约** + +公开入口是三个 @tool 装饰的异步函数:`wiki_ingest(source: str, workspace: str = "", force: bool = False, sys_operation: Optional[SysOperation] = None) -> str`(L470-475);`wiki_query(query: str, workspace: str = "", sys_operation: Optional[SysOperation] = None) -> str`(L530-532);`wiki_lint(workspace: str = "", sys_operation: Optional[SysOperation] = None) -> str`(L567)。错误契约:wiki_query 对空 query 直接返回 "Error: Query cannot be empty."(L534-535),wiki_query/wiki_lint 在 workspace 不存在时返回提示先使用 wiki_ingest 的错误字符串(L539-543、L572-576);wiki_ingest 对不存在的 source 返回 "Error: Source ... not found.",并以 try/except 把异常转成字符串返回而非抛出(L491-492、L520-521)。 + +Sources / 来源:[jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L470–L475](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/wiki_tools.py#L470-L475), [jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L530–L543](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/wiki_tools.py#L530-L543), [jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L567–L576](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/wiki_tools.py#L567-L576), [jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L491–L521](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/wiki_tools.py#L491-L521) + + + +**ingest 前置校验与 prompt 驱动的维护** + +Inference / 设计推断(非作者历史意图): + +ingest 路径在代码层面做的确定性校验包括:源文件存在性检查(不存在则抛 FileNotFoundError,L315-316)、SHA-256 去重(force=False 且已记录则跳过,L318-327),以及 wiki_ingest 目录模式下用 posix 路径前缀比对排除 .llm_wiki 工作区自身以避免循环导入(L494-505);其余知识提取、交叉链接与结构维护完全交给 LLM:ingest/lint 的指令是拼接的自然语言 prompt(L333-339、L357-364),manifest 仅在结果不含 "error" 且 output 不以 "[ERROR" 开头时记录哈希(L342-346)。这一取舍的代价是 wiki 内容质量依赖模型对 schema/AGENT.md 规则的遵循,代码不校验生成的 wiki 页面是否符合规则;收益是去重与防循环导入无需模型参与、行为可预测。 + +Sources / 来源:[jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L313–L347](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/wiki_tools.py#L313-L347), [jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L494–L505](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/wiki_tools.py#L494-L505), [jiuwenswarm/agents/harness/common/tools/wiki_tools.py:L356–L365](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/wiki_tools.py#L356-L365) + diff --git a/knowledge/repos/jiuwenswarm/components/agents-team/feature-pdf-reading-tool.md b/knowledge/repos/jiuwenswarm/components/agents-team/feature-pdf-reading-tool.md index 74b08446..c5a2e921 100644 --- a/knowledge/repos/jiuwenswarm/components/agents-team/feature-pdf-reading-tool.md +++ b/knowledge/repos/jiuwenswarm/components/agents-team/feature-pdf-reading-tool.md @@ -1,10 +1,10 @@ --- title: "read_pdf:分页 PDF 文本读取工具(feature-pdf-reading-tool)" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L170-L183, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L213-L218, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L244-L254, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L1-L10, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L239-L262, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L36-L41, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L273-L275, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L143-L168, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L185-L211, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L125-L130, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L112-L130, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L257-L275, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/agents/test_pdf_tools.py:L324-L335] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L170-L183, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L213-L218, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L244-L254, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L1-L10, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L239-L262, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L36-L41, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L273-L275, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L143-L168, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L185-L211, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L125-L130, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L112-L130, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L257-L275, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/agents/test_pdf_tools.py:L324-L335, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L24-L26, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L112-L122] feature: "pdf-reading-tool" entry_points: ["jiuwenswarm/agents/harness/common/tools/pdf_tools.py"] source_globs: ["jiuwenswarm/agents/harness/common/tools/pdf_tools.py"] @@ -56,3 +56,11 @@ Sources / 来源:[jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L143– Sources / 来源:[jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L112–L130](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/pdf_tools.py#L112-L130), [jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L257–L275](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/pdf_tools.py#L257-L275), [tests/unit_tests/agents/test_pdf_tools.py:L324–L335](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/agents/test_pdf_tools.py#L324-L335) + + +**read_pdf 的内部常量与入参规整** + +read_pdf 没有外部配置项,读取边界由模块级常量定义:`DEFAULT_MAX_CHARS = 50_000`(max_chars 缺省值)、`_MAX_CHARS_CEILING = 200_000`、`_MAX_PAGES_PER_CALL = 100`。`_normalize_request` 对 `max_chars` 做 `int()` 转换,仅当转换抛出 TypeError/ValueError(如 None 或 "abc")时才回退默认值,可转换的输入(如 "2000")会被采用;随后统一钳制到 `[1_000, 200_000]` 区间。工具描述通过 f-string 插值 `DEFAULT_MAX_CHARS` 与 `_MAX_PAGES_PER_CALL`(不含上限常量 `_MAX_CHARS_CEILING`),使模型可见的默认值与页数上限随常量自动同步。 + +Sources / 来源:[jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L24–L26](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/pdf_tools.py#L24-L26), [jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L112–L122](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/pdf_tools.py#L112-L122), [jiuwenswarm/agents/harness/common/tools/pdf_tools.py:L244–L254](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/pdf_tools.py#L244-L254) + diff --git a/knowledge/repos/jiuwenswarm/components/agents-team/feature-sdd-design-rail.md b/knowledge/repos/jiuwenswarm/components/agents-team/feature-sdd-design-rail.md index 71609cc7..5e103c22 100644 --- a/knowledge/repos/jiuwenswarm/components/agents-team/feature-sdd-design-rail.md +++ b/knowledge/repos/jiuwenswarm/components/agents-team/feature-sdd-design-rail.md @@ -1,10 +1,10 @@ --- title: "DesignRail SDD 状态机(Spec-Driven Development)" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py:L2-L17, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/code/rails/sdd/common/rail_state_machine.py:L101-L137, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/code/rails/sdd/common/rail_state_machine.py:L255-L301, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/code/rails/sdd/design_rail/__init__.py:L4-L12, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/code/rails/sdd/common/rail_state_machine.py:L297-L333, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py:L36-L53, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/code/rails/sdd/design_rail/skills/aet-req-analysis/scripts/assemble-template.mjs:L14-L20, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py:L48-L53, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py:L141-L149, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/code/rails/sdd/common/rail_state_machine.py:L8-L13, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/code/rails/sdd/design_rail/config_loader.py:L58-L72, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/code/rails/sdd/common/rail_state_machine.py:L255-L264, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/code/rails/sdd/common/rail_state_machine.py:L343-L365, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py:L70-L92, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py:L97-L149] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py:L2-L17, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/code/rails/sdd/common/rail_state_machine.py:L101-L137, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/code/rails/sdd/common/rail_state_machine.py:L255-L301, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/code/rails/sdd/design_rail/__init__.py:L4-L12, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/code/rails/sdd/common/rail_state_machine.py:L297-L333, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py:L36-L53, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/code/rails/sdd/design_rail/skills/aet-req-analysis/scripts/assemble-template.mjs:L14-L20, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py:L48-L53, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py:L141-L149, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/code/rails/sdd/common/rail_state_machine.py:L8-L13, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/code/rails/sdd/design_rail/config_loader.py:L58-L72, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/code/rails/sdd/common/rail_state_machine.py:L255-L264, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/code/rails/sdd/common/rail_state_machine.py:L343-L365, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py:L70-L92, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py:L97-L149, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/code/rails/sdd/design_rail/config_loader.py:L56-L135, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/sdd/design_rail/test_config_loader.py:L19-L30] feature: "sdd-design-rail" entry_points: ["jiuwenswarm/agents/harness/code/rails/sdd/common/rail_state_machine.py", "jiuwenswarm/agents/harness/code/rails/sdd/design_rail/__init__.py", "jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py"] source_globs: ["jiuwenswarm/agents/harness/code/rails/sdd/common/rail_state_machine.py", "jiuwenswarm/agents/harness/code/rails/sdd/design_rail/__init__.py", "jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py", "jiuwenswarm/agents/harness/code/rails/sdd/design_rail/skills/aet-req-analysis/scripts/assemble-checklist.mjs", "jiuwenswarm/agents/harness/code/rails/sdd/design_rail/skills/aet-req-analysis/scripts/assemble-template.mjs", "jiuwenswarm/agents/harness/code/rails/sdd/design_rail/skills/aet-req-design/scripts/assemble-checklist.mjs", "jiuwenswarm/agents/harness/code/rails/sdd/design_rail/skills/aet-req-design/scripts/assemble-template.mjs", "jiuwenswarm/agents/harness/code/rails/sdd/design_rail/config_loader.py", "jiuwenswarm/agents/harness/code/rails/sdd/__init__.py", "jiuwenswarm/agents/harness/code/rails/sdd/common/__init__.py"] @@ -54,3 +54,11 @@ DesignRail 的公开入口是关键字专属构造器 `DesignRail(*, rail_pkg_di Sources / 来源:[jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py:L70–L92](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py#L70-L92), [jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py:L97–L149](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py#L97-L149) + + +**config.yaml 声明式阶段配置与校验规则** + +DesignRail 的行为由 rail 包内 `config.yaml` 声明:`stages.` 可含 `skill`(技能名)、`artifacts`(产物文件列表,可选——评审阶段无产物)与 `next`(前进边列表);顶层 `priority` 键可覆盖构造参数默认值 60,`skills_dir` 缺省为 `skills/`。`config_loader.validate` 在挂载前执行声明式校验:核心阶段必须齐全、`next` 必须为列表、`done` 必须可从 `init` 经 next 边到达(`no_path_init_to_done` 拒绝把 done 圈死的环);提供 `rail_pkg_dir` 时还校验每个核心阶段声明的 skill 在 `///SKILL.md` 真实存在(`skill_file_not_found`),在挂载时拦截拼写错误而非运行时静默回退 bootstrap。校验失败时 DesignRail 构造函数抛 ValueError,由构建方(BC-005)拒绝挂载。测试文件 test_config_loader.py 以镜像 config.yaml 的 `_valid_config()` 复现这些规则(helper 单元测试入口,未执行)。 + +Sources / 来源:[jiuwenswarm/agents/harness/code/rails/sdd/design_rail/config_loader.py:L56–L135](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/code/rails/sdd/design_rail/config_loader.py#L56-L135), [jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py:L70–L92](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/code/rails/sdd/design_rail/rail.py#L70-L92), [tests/unit_tests/sdd/design_rail/test_config_loader.py:L19–L30](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/sdd/design_rail/test_config_loader.py#L19-L30) + diff --git a/knowledge/repos/jiuwenswarm/components/agents-team/feature-xiaoyi-alarm-crud.md b/knowledge/repos/jiuwenswarm/components/agents-team/feature-xiaoyi-alarm-crud.md index 1f6a1d51..87564bbc 100644 --- a/knowledge/repos/jiuwenswarm/components/agents-team/feature-xiaoyi-alarm-crud.md +++ b/knowledge/repos/jiuwenswarm/components/agents-team/feature-xiaoyi-alarm-crud.md @@ -1,10 +1,10 @@ --- title: "小艺手机工具 — 设备闹钟 CRUD(create/search/modify/delete_alarm)" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py:L320-L333, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py:L263-L288, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L58-L96, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L168-L207, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py:L596-L601, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py:L205-L221, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L87-L104, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py:L263-L278, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py:L286-L292, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L210-L228] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py:L320-L333, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py:L263-L288, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L58-L96, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L168-L207, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py:L596-L601, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py:L205-L221, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L87-L104, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py:L263-L278, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py:L286-L292, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L210-L228, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py:L450-L455, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py:L240-L247, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py:L517-L527, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py:L191-L202, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py:L334-L340, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py:L456-L468, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L247-L269, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py:L349-L377, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py:L471-L495] feature: "xiaoyi-alarm-crud" entry_points: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py"] source_globs: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py", "jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py", "jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py", "jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/contact_tools.py"] @@ -44,3 +44,29 @@ Sources / 来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/a Sources / 来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py:L286–L292](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py#L286-L292), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L210–L228](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py#L210-L228) + + +**部分更新的覆盖风险与 days_of_week 的不一致处理** + +Inference / 设计推断(非作者历史意图): + +`modify_alarm` 的 docstring 明确提示:修改未涉及字段若希望保持原值,宜先 `search_alarms` 取原值再一并传入,避免默认覆盖——即设备侧修改可能用默认值填充未传字段(此为文档声明的设计权衡)。另外对「`days_of_week` 配合非 3 的 `days_of_wake_type`」处理不一致:创建路径仅记 warning 并忽略,修改路径在 `days_of_wake_type=None` 时直接抛 `ToolInputError`。 + +Sources / 来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py:L450–L455](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py#L450-L455), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py:L240–L247](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py#L240-L247), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py:L517–L527](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py#L517-L527) + + + +**异步工具函数契约与统一响应格式** + +四个闹钟操作均以带 Optional 类型注解的 async 函数形式定义:create_alarm 接受 alarm_time 或 hour+minute 等参数,search_alarms 接受五个可选过滤参数,modify_alarm 接受 entity_id/alarm_id 及可选字段,delete_alarm 接受 items 或 alarm_id。参数校验失败抛出 ToolInputError(该异常携带 status=400,docstring 说明框架会返回 HTTP 400 而非 500),且各工具的 except 分支会原样重新抛出 ToolInputError、仅把其他异常包装为 RuntimeError。成功路径统一经 format_success_response 返回 {"content":[{"type":"text","text": JSON}]} 形式的字典。 + +Sources / 来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py:L191–L202](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py#L191-L202), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py:L334–L340](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py#L334-L340), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py:L456–L468](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py#L456-L468), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py:L247–L269](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/utils.py#L247-L269) + + + +**可组合检索条件与 modify 的兼容别名** + +search_alarms 支持可组合的检索条件(range_type、alarm_state、days_of_wake_type、成对的 start_time/end_time);当全部条件缺省时自动回退为 range_type="all",start_time 与 end_time 必须成对提供且 start 早于 end,时间区间转换为设备侧 timeInterval 毫秒数组。modify_alarm 兼容两种入参别名:entity_id 与 alarm_id 均指向设备侧闹钟实体 ID(缺失时抛 ToolInputError),enabled 布尔在 alarm_state 未提供时映射为 1/0;docstring 同时提示修改未涉及字段时宜先 search_alarms 取原值再一并传入,避免默认覆盖。 + +Sources / 来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py:L349–L377](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py#L349-L377), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py:L471–L495](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py#L471-L495), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py:L450–L455](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/alarm_tools.py#L450-L455) + diff --git a/knowledge/repos/jiuwenswarm/components/agents-team/feature-xiaoyi-calendar-tools.md b/knowledge/repos/jiuwenswarm/components/agents-team/feature-xiaoyi-calendar-tools.md index df397162..242833eb 100644 --- a/knowledge/repos/jiuwenswarm/components/agents-team/feature-xiaoyi-calendar-tools.md +++ b/knowledge/repos/jiuwenswarm/components/agents-team/feature-xiaoyi-calendar-tools.md @@ -1,10 +1,10 @@ --- title: "Xiaoyi 设备日历日程工具(create/search_calendar_event)" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L131-L171, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L237-L281, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L106-L110, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L276-L287, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L137-L161, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L244-L261, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L120-L135, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L222-L235, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L264-L274] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L131-L171, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L237-L281, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L106-L110, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L276-L287, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L137-L161, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L244-L261, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L120-L135, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L222-L235, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L264-L274, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L87-L89, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L193-L195, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L120-L129, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L222-L229, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L91-L95, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L113-L118, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L198-L202, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L283-L287] feature: "xiaoyi-calendar-tools" entry_points: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py"] source_globs: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py"] @@ -46,3 +46,21 @@ create 将 `yyyy-mm-dd hh:mm:ss` 字符串经 `datetime.strptime` 转为毫秒 Sources / 来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L120–L135](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py#L120-L135), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L222–L235](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py#L222-L235), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L264–L274](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py#L264-L274) + + +**时间格式不统一与提示层超时约束** + +Inference / 设计推断(非作者历史意图): + +推断(无作者意图的文档证据):两个工具采用不同的时间输入格式——create 用 `yyyy-mm-dd hh:mm:ss`(datetime.strptime 校验),search 用 `YYYYMMDD hhmmss`(_parse_time_string_ymd_hhmmss 校验)——各自匹配工具描述,但调用方需按工具区分格式。另外,工具描述声称执行最长可达 60 秒并要求“勿重复调用、最多重试一次、先获取当前真实时间”,这是提示层约束;所示代码中唯一的数值超时是设备命令里的 timeOut: 5,未见代码层强制 60 秒上限或重试限制。 + +Sources / 来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L87–L89](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py#L87-L89), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L193–L195](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py#L193-L195), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L120–L129](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py#L120-L129), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L222–L229](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py#L222-L229) + + + +**工具入口与错误契约** + +两个公开入口均为用 `@tool` 装饰的异步可调用工具:`create_calendar_event(title, dt_start, dt_end)` 和 `search_calendar_event(start_time, end_time, title=None)`,返回 `Dict[str, Any]`。当传入空字符串(如 `title`/`dt_start`/`dt_end` 或 `start_time`/`end_time` 为空、时间格式非法)时,函数体内抛出 `ToolInputError` 且不被兜底 except 转换;其余异常被包装为 `RuntimeError`(中文消息「创建日程失败/搜索日程失败」)重新抛出。成功时通过 `format_success_response` 返回包含结果或日程列表的字典。 + +Sources / 来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L91–L95](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py#L91-L95), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L113–L118](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py#L113-L118), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L198–L202](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py#L198-L202), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py:L283–L287](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/calendar_tools.py#L283-L287) + diff --git a/knowledge/repos/jiuwenswarm/components/agents-team/feature-xiaoyi-location-tool.md b/knowledge/repos/jiuwenswarm/components/agents-team/feature-xiaoyi-location-tool.md index dc4b9996..58b1eb06 100644 --- a/knowledge/repos/jiuwenswarm/components/agents-team/feature-xiaoyi-location-tool.md +++ b/knowledge/repos/jiuwenswarm/components/agents-team/feature-xiaoyi-location-tool.md @@ -1,10 +1,10 @@ --- title: "设备定位工具 get_user_location(feature-xiaoyi-location-tool)" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py:L19-L31, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py:L68-L86, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py:L33-L68, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py:L19-L26, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py:L41-L54, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py:L68-L73, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py:L67-L73] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py:L19-L31, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py:L68-L86, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py:L33-L68, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py:L19-L26, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py:L41-L54, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py:L68-L73, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py:L67-L73, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py:L14-L17] feature: "xiaoyi-location-tool" entry_points: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py"] source_globs: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py"] @@ -54,3 +54,11 @@ Sources / 来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/l Sources / 来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py:L19–L26](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py#L19-L26), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py:L41–L54](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py#L41-L54), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py:L67–L73](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py#L67-L73) + + +**验证与运行时防护** + +所示输入不含任何自动化测试:location_tool.py 是纯工具实现文件,整个文件(L1–L86)没有测试函数或测试入口,也未展示针对该工具的测试文件。代码中实际存在的校验是运行时防护而非测试:L70–L71 将非 dict 的设备返回归一化为 {"value": outputs},随后 L73 调用共享辅助函数 raise_if_device_error(outputs, "获取位置失败") 做设备错误检查。该辅助函数与 execute_device_command 的内部校验/超时行为在所示代码中不可见(仅 L16 导入),因此无法断言完整错误处理范围。 + +Sources / 来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py:L68–L73](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py#L68-L73), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py:L14–L17](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/location_tool.py#L14-L17) + diff --git a/knowledge/repos/jiuwenswarm/components/agents-team/feature-xiaoyi-save-to-phone-tools.md b/knowledge/repos/jiuwenswarm/components/agents-team/feature-xiaoyi-save-to-phone-tools.md index 2600ce72..c7ddf6dd 100644 --- a/knowledge/repos/jiuwenswarm/components/agents-team/feature-xiaoyi-save-to-phone-tools.md +++ b/knowledge/repos/jiuwenswarm/components/agents-team/feature-xiaoyi-save-to-phone-tools.md @@ -1,10 +1,10 @@ --- title: "小艺保存到手机工具(save_media_to_gallery / save_file_to_file_manager)" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py:L43-L54, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/file_upload_helpers.py:L51-L59, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py:L21-L26, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py:L102-L146, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py:L227-L255, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py:L164-L168, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/file_upload_helpers.py:L60-L67, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/file_upload_helpers.py:L74-L81, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/file_upload_helpers.py:L85-L92, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py:L29-L40, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/file_upload_helpers.py:L25-L59, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/file_upload_helpers.py:L74-L92] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py:L43-L54, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/file_upload_helpers.py:L51-L59, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py:L21-L26, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py:L102-L146, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py:L227-L255, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py:L164-L168, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/file_upload_helpers.py:L60-L67, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/file_upload_helpers.py:L74-L81, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/file_upload_helpers.py:L85-L92, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py:L29-L40, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/file_upload_helpers.py:L25-L59, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/file_upload_helpers.py:L74-L92, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/file_upload_helpers.py:L36-L43, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/file_upload_helpers.py:L68-L81, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py:L119-L144, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py:L227-L253] feature: "xiaoyi-save-to-phone-tools" entry_points: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py"] source_globs: ["jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py", "jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/file_upload_helpers.py"] @@ -44,3 +44,13 @@ Sources / 来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/s Sources / 来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py:L29–L40](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py#L29-L40), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/file_upload_helpers.py:L25–L59](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/file_upload_helpers.py#L25-L59), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/file_upload_helpers.py:L74–L92](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/file_upload_helpers.py#L74-L92) + + +**上传路径的取舍:整文件内存读取与服务端驱动协议** + +Inference / 设计推断(非作者历史意图): + +(推断)本地文件上传采用三段式服务端驱动协议:prepare 返回的 `uploadInfos[0]` 决定上传的 method(缺省 PUT)、目标 url 和 headers,工具照办——换取对服务端上传策略的适配能力,代价是上传行为不由客户端控制。且文件被完整读入内存(`f.read()`)并整体作为请求体发送,同时计算 SHA-256 随 prepare 提交;对大文件这意味着整个文件驻留内存。已是 `http://`/`https://` 的 URL 直接透传跳过上传。另外,两个工具的设备命令 permissionId 都固定为 `ohos.permission.WRITE_IMAGEVIDEO`(保存普通文件也复用该媒体权限),且 `SaveFileToFileManager` 的 executeParam 同时写了 `timeOut: 5` 与 `timeout: 55000` 两个大小写不同的键,`SaveMediaToGallery` 只有前者。 + +Sources / 来源:[jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/file_upload_helpers.py:L36–L43](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/file_upload_helpers.py#L36-L43), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/file_upload_helpers.py:L68–L81](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/file_upload_helpers.py#L68-L81), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py:L119–L144](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py#L119-L144), [jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py:L227–L253](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/tools/xiaoyi_phone_tools/save_tools.py#L227-L253) + diff --git a/knowledge/repos/jiuwenswarm/components/browser-client/knowledge.md b/knowledge/repos/jiuwenswarm/components/browser-client/knowledge.md index bbe5cbf7..26c743de 100644 --- a/knowledge/repos/jiuwenswarm/components/browser-client/knowledge.md +++ b/knowledge/repos/jiuwenswarm/components/browser-client/knowledge.md @@ -1,10 +1,10 @@ --- title: "JiuwenSwarm browser-client(Chromium 扩展)背景服务与内容脚本" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/browser/frontend/src/background/index.ts:L1-L13, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/browser/frontend/src/background/index.ts:L70-L93, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/browser/frontend/src/background/ToolDispatcher.ts:L48-L104, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/browser/frontend/src/background/WsClient.ts:L89-L99, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/browser/frontend/src/content/Extractor.ts:L33-L56, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/browser/frontend/src/background/ContextMenu.ts:L91-L111, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/browser/frontend/eslint.config.js:L3-L13, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/browser/frontend/scripts/pack.js:L19-L29, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/browser/frontend/scripts/pack.js:L44-L48] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/browser/frontend/src/background/index.ts:L1-L13, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/browser/frontend/src/background/index.ts:L70-L93, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/browser/frontend/src/background/ToolDispatcher.ts:L48-L104, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/browser/frontend/src/background/WsClient.ts:L89-L99, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/browser/frontend/src/content/Extractor.ts:L33-L56, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/browser/frontend/src/background/ContextMenu.ts:L91-L111, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/browser/frontend/eslint.config.js:L3-L13, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/browser/frontend/scripts/pack.js:L19-L29, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/browser/frontend/scripts/pack.js:L44-L48, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/browser/frontend/src/background/PanelManager.ts:L1-L10, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/browser/frontend/src/background/PanelManager.ts:L33-L39, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/browser/frontend/src/background/PanelManager.ts:L54-L75] --- # JiuwenSwarm browser-client(Chromium 扩展)背景服务与内容脚本 @@ -41,3 +41,13 @@ eslint.config.js 基于 typescript-eslint recommended,忽略 dist/、node_modu Sources / 来源:[jiuwenswarm/channels/browser/frontend/eslint.config.js:L3–L13](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/browser/frontend/eslint.config.js#L3-L13), [jiuwenswarm/channels/browser/frontend/scripts/pack.js:L19–L29](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/browser/frontend/scripts/pack.js#L19-L29), [jiuwenswarm/channels/browser/frontend/scripts/pack.js:L44–L48](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/browser/frontend/scripts/pack.js#L44-L48) + + +**Side Panel 能力检测与弹窗回退的取舍** + +Inference / 设计推断(非作者历史意图): + +PanelManager 以运行时检测 chrome.sidePanel 是否存在来分支(推断:这是为兼容不支持 Side Panel API 的 Chromium 系浏览器而保留的降级路径,文件头注释点名 360/QQ/搜狗浏览器)。原生分支仅在调用方传入 windowId 时才调用 chrome.sidePanel.open,否则直接返回不打开;回退分支以 420×700 的初始尺寸新建 popup,已打开时仅聚焦复用,窗口关闭时通过 onRemoved 清理记录的 ID。 + +Sources / 来源:[jiuwenswarm/channels/browser/frontend/src/background/PanelManager.ts:L1–L10](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/browser/frontend/src/background/PanelManager.ts#L1-L10), [jiuwenswarm/channels/browser/frontend/src/background/PanelManager.ts:L33–L39](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/browser/frontend/src/background/PanelManager.ts#L33-L39), [jiuwenswarm/channels/browser/frontend/src/background/PanelManager.ts:L54–L75](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/browser/frontend/src/background/PanelManager.ts#L54-L75) + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/_index.md b/knowledge/repos/jiuwenswarm/components/config-resources/_index.md index f6ca219d..06f8b18c 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/_index.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/_index.md @@ -86,3 +86,89 @@ sources: [] - [XLSX 技能环境自检(doctor.py)](feature-xlsx-doctor-selfcheck.md) - [符号审计完整性 HMAC 签名与信任验证(audit_integrity.py)](feature-audit-integrity-hmac-signing.md) - [openJiuwen-DeepSearch 深度研究执行管线](feature-deepsearch-research-pipeline.md) + +- [Agent 模板分层校验器(L0 规范 / L1 静态 AST / L2 子进程编排):实现深读](feature-depth-agent-template-layered-validation.md) + +- [arXiv 论文 Figure/Table 检测与高清导出(extract_arxiv_visuals):实现深读](feature-depth-arxiv-visual-extraction.md) + +- [Chrome Trace JSON 生成器(trace_collector):实现深读](feature-depth-ascend-chrome-trace-generator.md) + +- [ascend-moe-optimizer-trace-analyzer CLI 主流程:实现深读](feature-depth-ascend-trace-analysis-pipeline.md) + +- [TRACE_POINT 自动埋点改写(instrument_operator):实现深读](feature-depth-ascend-trace-auto-instrumentation.md) + +- [插桩编译安全静态检查器:实现深读](feature-depth-ascend-trace-compile-safety-checker.md) + +- [插桩计划生成器(调用图深度受限展开):实现深读](feature-depth-ascend-trace-instrumentation-planner.md) + +- [TRACE_POINT 预处理器与 point_map 映射导出:实现深读](feature-depth-ascend-trace-preprocessor.md) + +- [符号审计完整性 HMAC 签名与信任验证(audit_integrity.py):实现深读](feature-depth-audit-integrity-hmac-signing.md) + +- [自包含审计可视化 HTML 报告生成器:实现深读](feature-depth-audit-report-html-renderer.md) + +- [Cross-Channel Session History Search Skill:实现深读](feature-depth-cross-channel-history-search-skill.md) + +- [进阶版日报/周报/月报生成器 Skill:实现深读](feature-depth-daily-report-skill.md) + +- [openJiuwen-DeepSearch 深度研究执行管线:实现深读](feature-depth-deepsearch-research-pipeline.md) + +- [docx-pro Word 文档操作 CLI:实现深读](feature-depth-docx-pro-cli.md) + +- [财务文档解析 Skill(发票/收据/对账单解析与报告生成):实现深读](feature-depth-financial-document-parser.md) + +- [GitHub Issue 反馈创建脚本:实现深读](feature-depth-github-issue-feedback-script.md) + +- [华为云 MaaS API Key 自动创建与捕获(auto_create_apikey):实现深读](feature-depth-huawei-maas-apikey-creation.md) + +- [华为云 MaaS 委托授权自动化(auto_authorize):实现深读](feature-depth-huawei-maas-cdp-authorize.md) + +- [华为云账号实名认证状态检测(check_account):实现深读](feature-depth-huawei-realname-account-check.md) + +- [本地离线 OCR 管线(RapidOCR:PDF/图片 → Markdown):实现深读](feature-depth-local-doc-ocr-offline.md) + +- [华为云 MaaS 预置服务批量开通自动化(CDP):实现深读](feature-depth-maas-auto-open-models.md) + +- [解包 PPTX 幻灯片添加工具(opc/add_slide.py):实现深读](feature-depth-opc-add-slide.md) + +- [OOXML 打包与 schema 校验(opc/pack.py):实现深读](feature-depth-opc-pack-validate.md) + +- [plugin-creator 插件包脚手架初始化:实现深读](feature-depth-plugin-package-initializer.md) + +- [plugin-creator 插件包分层校验器(L0/L1/L2):实现深读](feature-depth-plugin-package-layered-validator.md) + +- [一键成片流水线与质量门禁(finalize_deck.py):实现深读](feature-depth-ppt-deck-finalize.md) + +- [Evidence Plan Preparation and Review Lifecycle:实现深读](feature-depth-ppt-evidence-preparation.md) + +- [PPT 执行锁(execution-lock.json)语义校验器:实现深读](feature-depth-ppt-execution-lock-validator.md) + +- [PPT 图表面板布局引擎(figure-panel.js):实现深读](feature-depth-ppt-figure-panel-layout.md) + +- [Deck Thumbnail Contact-Sheet Renderer:实现深读](feature-depth-ppt-opc-thumbnail.md) + +- [PPT 系统架构图原生形状渲染引擎:实现深读](feature-depth-ppt-system-diagram-renderer.md) + +- [PPTX 结构与可读性审计脚本:实现深读](feature-depth-pptx-structural-audit.md) + +- [RSI 数据集任务文件夹完整性预检:实现深读](feature-depth-rsi-dataset-folder-check.md) + +- [skill-gen CLI(sop-text / url-fetch 子命令):实现深读](feature-depth-skill-generator-cli.md) + +- [Web Page Scraping to Unified Stage01 Blocks:实现深读](feature-depth-skill-page-scrape-blocks.md) + +- [SOP 结构化抽取(parse_sop_raw_text / parse_sop_file):实现深读](feature-depth-sop-structure-extraction.md) + +- [视频粗扫抽帧与审核批次门控(analyze_video.py):实现深读](feature-depth-video-coarse-scan-frame-extraction.md) + +- [XLSX Computed Column Adder:实现深读](feature-depth-xlsx-add-computed-column.md) + +- [XLSX 技能环境自检(doctor.py):实现深读](feature-depth-xlsx-doctor-selfcheck.md) + +- [XLSX 公式静态校验(formula_check.py):实现深读](feature-depth-xlsx-formula-check.md) + +- [XLSX Row Insert with Range Extension:实现深读](feature-depth-xlsx-insert-row.md) + +- [XLSX Read-Only Structure Reader and Edit-Damage Differ:实现深读](feature-depth-xlsx-reader-structural-diff.md) + +- [XLSX Skill Format-Preserving Unpack/Repack:实现深读](feature-depth-xlsx-workbook-unpack-repack.md) diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-agent-template-layered-validation.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-agent-template-layered-validation.md index f1c4c404..be41a4b7 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-agent-template-layered-validation.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-agent-template-layered-validation.md @@ -1,10 +1,10 @@ --- title: "Agent 模板分层校验器(validate_template.py / validate_hot_load_worker.py)" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py:L10-L14, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py:L949-L987, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_hot_load_worker.py:L1-L11, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py:L1-L8, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py:L860-L907, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_hot_load_worker.py:L1-L5, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py:L915-L946, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_hot_load_worker.py:L150-L155, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py:L148-L173, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py:L953-L959, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py:L972-L974, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py:L35-L36] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py:L10-L14, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py:L949-L987, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_hot_load_worker.py:L1-L11, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py:L1-L8, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py:L860-L907, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_hot_load_worker.py:L1-L5, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py:L915-L946, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_hot_load_worker.py:L150-L155, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py:L148-L173, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py:L953-L959, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py:L972-L974, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py:L35-L36, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py:L937-L941, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py:L975-L987] feature: "agent-template-layered-validation" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py", "jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_hot_load_worker.py"] @@ -46,3 +46,13 @@ Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/agent-creator/s Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py:L148–L173](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py#L148-L173), [jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py:L953–L959](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py#L953-L959), [jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py:L972–L974](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py#L972-L974), [jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py:L35–L36](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py#L35-L36) + + +**分层门控与 SKIP 语义的取舍** + +Inference / 设计推断(非作者历史意图): + +推断:L0/L1 全部通过才执行 L2 的门控让廉价的 stdlib 静态检查先行,只有静态干净的包才付出子进程热加载成本;但代价是环境性问题(openjiuwen 未安装、环境搭建失败、worker 超时或启动失败、stdout 不可解析)一律归为 SKIP 而非 FAIL,汇总输出 RESULT: PARTIAL 并明确提示“SKIP 不等于通过”,整体退出码要求三层全部 PASS 才为 0。SKIP 的修复提示按来源区分:环境问题建议检查 openjiuwen 运行环境,超时提示检查包内在 import/绑定阶段卡住的 tool/rail,启动失败提示检查 python 与 worker 脚本。 + +Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py:L860–L907](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py#L860-L907), [jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py:L937–L941](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py#L937-L941), [jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py:L975–L987](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_template.py#L975-L987), [jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_hot_load_worker.py:L150–L155](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/agent-creator/scripts/validate_hot_load_worker.py#L150-L155) + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-arxiv-visual-extraction.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-arxiv-visual-extraction.md index 5a1dbda1..dfe7a0fc 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-arxiv-visual-extraction.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-arxiv-visual-extraction.md @@ -1,10 +1,10 @@ --- title: "extract_arxiv_visuals v2.2 — arXiv 论文 Figure/Table 检测与高清导出" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L1203-L1217, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L962-L997, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L423-L432, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L1363-L1406, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L50-L56, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L125-L130, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L1410-L1471, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L1191-L1196, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L1363-L1369, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L22-L24, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L96-L127, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L891-L897, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L1334-L1337, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L1413-L1437, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L1126-L1148, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L1168-L1177] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L1203-L1217, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L962-L997, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L423-L432, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L1363-L1406, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L50-L56, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L125-L130, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L1410-L1471, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L1191-L1196, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L1363-L1369, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L22-L24, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L96-L127, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L891-L897, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L1334-L1337, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L1413-L1437, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L1126-L1148, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L1168-L1177, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L1259-L1274, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L1121-L1128, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L1298-L1302] feature: "arxiv-visual-extraction" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py"] @@ -52,3 +52,11 @@ main() 在解析后用 parser.error 校验 --dpi/--debug-dpi 必须为正、--pa Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L1413–L1437](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py#L1413-L1437), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L1126–L1148](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py#L1126-L1148), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L1168–L1177](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py#L1168-L1177) + + +**支持的输出行为及其条件** + +提取成功时,每个候选写入两张 PNG:figures/(或 tables/)下的内容图,以及 *_with_caption 变体——仅当 region 与 caption bbox 可合并时才渲染合并区域,否则直接复制内容图,因此 caption 变体并不保证包含 caption;单个候选渲染失败不会中断流程,而是记入 manifest 的 failures。辅助产物是条件性的:debug/ 标注页只为含候选的页面生成,contact_sheet.png 在没有任何成功缩略图时跳落不生成,pages/ 全页 PNG 仅在 --keep-pages 时输出。 + +Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L1259–L1274](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py#L1259-L1274), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L1121–L1128](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py#L1121-L1128), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L1168–L1177](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py#L1168-L1177), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L1298–L1302](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py#L1298-L1302) + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-ascend-chrome-trace-generator.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-ascend-chrome-trace-generator.md index c809f484..ea899e58 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-ascend-chrome-trace-generator.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-ascend-chrome-trace-generator.md @@ -1,10 +1,10 @@ --- title: "Chrome Trace JSON 生成器(trace_collector)" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L32-L55, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L22-L29, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L338-L352, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_utils.py:L124-L148, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L372-L382, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_utils.py:L71-L85, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L367-L400, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L58-L90, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/verify_trace_scaffold.py:L14-L54, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L104-L125, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L338-L363] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L32-L55, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L22-L29, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L338-L352, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_utils.py:L124-L148, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L372-L382, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_utils.py:L71-L85, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L367-L400, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L58-L90, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/verify_trace_scaffold.py:L14-L54, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L104-L125, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L338-L363, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L250-L286, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L287-L319, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L128-L162, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L321-L336] feature: "ascend-chrome-trace-generator" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py", "jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_save.py", "jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_utils.py", "jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/inspect_rank_pt.py", "jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/bootstrap_trace_toolchain.py", "jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/verify_trace_scaffold.py"] @@ -44,3 +44,19 @@ verify_trace_scaffold.py 检查构建目录是否包含 trace_preprocessor/trace Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/verify_trace_scaffold.py:L14–L54](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/verify_trace_scaffold.py#L14-L54), [jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L104–L125](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py#L104-L125), [jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L338–L363](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py#L338-L363) + + +**B/E 配对的两种模式** + +generate_chrome_trace 按 (rank, core_type, core_id) 分组、再按 base_name 分组后做 B/E 配对,有两种模式。seq 模式(默认):每个 B 事件在同一 base_name 组内按时间顺序向后查找第一个 seq(extra_id 高 24 位)相同的 E 事件,找到则组成区间并将外层下标直接推进到该 E 之后——位于 B 与匹配 E 之间的中间记录既不配对也不进入 unpaired;未找到匹配 E 的 B 以及先于任何 B 出现的 E 记为 unpaired。legacy 模式:用 deque 做 FIFO 配对,每个 B 依入队顺序取得递增编号,多余的 E 标为 #-1、剩余未闭合的 B 也进入 unpaired。 + +Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L250–L286](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py#L250-L286), [jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L287–L319](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py#L287-L319) + + + +**深度过滤的区间树代价** + +当 depth 参数非 0 时,generate_chrome_trace 对每个线程的全部已配对区间调用 build_interval_tree 计算嵌套深度,再只保留 depth_from_leaf <= depth 的区间(unpaired 事件不受过滤影响,始终输出)。代价:build_interval_tree 对每个区间在全部区间上做二次扫描确定父节点(候选父须满足 oth.s <= cur.s 且 oth.e >= cur.e 且时长严格大于当前区间),随后 DFS 求深度,单线程内为 O(n²);depth 为 0 时跳过整棵树的构建,直接输出所有区间。 + +Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L128–L162](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py#L128-L162), [jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py:L321–L336](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ascend-moe-optimizer-auto-trace/scripts/trace_collector.py#L321-L336) + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-audit-integrity-hmac-signing.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-audit-integrity-hmac-signing.md index 49f0a3a1..638fc7a9 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-audit-integrity-hmac-signing.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-audit-integrity-hmac-signing.md @@ -1,10 +1,10 @@ --- title: "符号审计完整性 HMAC 签名与信任验证(audit_integrity.py)" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L654-L663, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L122-L154, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L681-L693, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L135-L154, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L466-L490, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L484-L490, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L235-L258, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L593-L623] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L654-L663, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L122-L154, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L681-L693, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L135-L154, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L466-L490, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L484-L490, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L235-L258, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L593-L623, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L384-L408, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L547-L570, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L454-L503, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L372-L376] feature: "audit-integrity-hmac-signing" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py"] @@ -38,3 +38,19 @@ Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/project-maintai Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L484–L490](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py#L484-L490), [jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L235–L258](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py#L235-L258), [jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L593–L623](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py#L593-L623) + + +**promote 写入签名元数据,verify 仅对 agent_audited 记录重验** + +`promote` 定位 audit map 中的 symbol 记录后,把 source/symbol/entry_doc 哈希、git HEAD 与状态等信息写入 `record["integrity"]`,对去掉自引用字段后的记录计算 `payload_hash` 并用 `hmac_signature` 生成 HMAC 签名,最后回写 audit map(L384–L408)。当未提供 `--agent-call-signature-json` 时,状态记为 `script_assessed` 并从记录中删除 `agent_call_signature_batch`(L365、L377–L381)。验证侧 `verify_or_report` 只对 `audit.status == "agent_audited"` 的记录调用 `verify_agent_record`,其余状态走各自的代码路径(L547–L570)。 + +Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L384–L408](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py#L384-L408), [jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L547–L570](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py#L547-L570) + + + +**agent 审计信任分级** + +`verify_agent_record` 实际返回三种信任结果:`invalid_agent_audit`(缺少签名或批次、generated_by/script_hash/payload_hash/签名不符,或 stale 哈希变化,L454–L498)、`suspicious_agent_audit` 与 `trusted_agent_audit`;第四种 `provisional_agent_audit` 是 `promote` 在提供签名批次时的输出代码,不出现在验证路径(L372–L376、L502–L503)。批次复用超过阈值只有在 invalid/stale 检查都未失败时才使记录返回 `suspicious_agent_audit`(L491–L501)。 + +Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L454–L503](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py#L454-L503), [jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py:L372–L376](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/audit_integrity.py#L372-L376) + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-audit-report-html-renderer.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-audit-report-html-renderer.md index 2bf52ef3..3c4279ff 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-audit-report-html-renderer.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-audit-report-html-renderer.md @@ -1,10 +1,10 @@ --- title: "自包含审计可视化 HTML 报告生成器(render_audit_report.py)" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L546-L555, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L22-L39, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L82-L112, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L147-L176, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L462-L505, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L42-L53, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L531-L543, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L365-L371, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L217-L247, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L512-L528, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L188-L216, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L318-L362] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L546-L555, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L22-L39, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L82-L112, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L147-L176, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L462-L505, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L42-L53, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L531-L543, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L365-L371, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L217-L247, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L512-L528, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L188-L216, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L318-L362, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L30-L39] feature: "audit-report-html-renderer" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py"] @@ -54,3 +54,11 @@ Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/project-maintai Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L512–L528](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py#L512-L528), [jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L188–L216](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py#L188-L216), [jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L318–L362](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py#L318-L362) + + +**运行时输入校验与完整性子进程检查** + +该脚本在所示源码中没有独立的自动化测试入口,验证以运行时守卫(runtime guards)形式内建。`read_json` 读取 coverage-map.json 与 symbol-audit-map.json 时捕获 FileNotFoundError 与 json.JSONDecodeError 并校验顶层必须是 JSON 对象,统一转为用户可见的 `AuditReportError`,由 `main` 打印到 stderr 并以退出码 1 结束(30-39, 546-555)。对完整性刷新子进程 `audit_integrity.py report`,代码检查 returncode 非零和 stdout 非法 JSON 两种失败,均不抛异常而是降级为 `status: failed` 的完整性状态继续生成报告(217-247),浏览器端状态行据此显示警告(502-504)。这些是执行期守卫而非测试;本仓库所示输入中未出现针对该脚本的 pytest 用例或测试文件。 + +Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L30–L39](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py#L30-L39), [jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L546–L555](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py#L546-L555), [jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py:L217–L247](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/project-maintainer/scripts/render_audit_report.py#L217-L247) + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-deepsearch-research-pipeline.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-deepsearch-research-pipeline.md index 5cea19ed..d1eb7684 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-deepsearch-research-pipeline.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-deepsearch-research-pipeline.md @@ -1,10 +1,10 @@ --- title: "openJiuwen-DeepSearch 深度研究执行管线" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py:L200-L230, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py:L293-L339, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py:L233-L258] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py:L200-L230, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py:L293-L339, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py:L233-L258, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py:L141-L197, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py:L41-L49, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py:L70-L127, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py:L36-L39, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py:L98-L127] feature: "deepsearch-research-pipeline" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py", "jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/validate_environment.py", "jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/convert_docx.py", "jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/convert_html.py", "jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/verify_skill_structure.py"] @@ -20,3 +20,27 @@ source_globs: ["jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSear Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py:L200–L230](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py#L200-L230), [jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py:L293–L339](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py#L293-L339), [jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py:L233–L258](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py#L233-L258) + + +**配置来源与固定分支默认值** + +配置来自 `SKILL_ROOT`(环境变量 `SKILL_ROOT`,默认脚本上级目录)下的 `.env`(python-dotenv 加载)。必需环境变量包括 `LLM_MODEL_NAME/LLM_MODEL_TYPE/LLM_BASE_URL/LLM_API_KEY` 与 `WEB_SEARCH_ENGINE_NAME/WEB_SEARCH_API_KEY/WEB_SEARCH_URL`,缺失即在 `load_agent_config` 抛 ValueError。可选 `MAX_WEB_SEARCH_RESULTS`(默认 "5")与 `EXECUTION_METHOD`(默认 "parallel",仅当等于 DEPENDENCY_DRIVING 枚举值才改用依赖驱动)。代码还硬编码分支默认:`search_mode="research"`、`outliner_max_section_num=5`、人机交互与大纲交互均关闭,且导入时强制设置 `LLM_SSL_VERIFY=false`、`TOOL_SSL_VERIFY=false`。 + +Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py:L141–L197](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py#L141-L197), [jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py:L41–L49](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py#L41-L49) + + + +**执行链路与报告产出** + +`execute_deep_search(query)` 先用 `load_agent_config()` 组装配置,再经 `asyncio.run` 调用 `run_jiuwen_workflow`:该协程实例化 `AgentFactory` 并调用其实例方法 `create_agent(agent_config)`,随后异步消费 `agent.run(...)` 的流式 chunk,对每个 chunk 做 `parse_endnode_content` 判定;只要 `full_report` 仍为假值就取该节点的 `response_content` 并清洗引用标记,因此空报告可被后续节点覆盖。最终报告写入 Markdown 并转换为 HTML/DOCX。 + +Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py:L200–L230](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py#L200-L230), [jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py:L70–L127](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py#L70-L127) + + + +**报告引用清洗与多格式导出** + +报告文本在返回前做两种引用标记清洗:`CHECKED_CITATION_RE` 把 `[checked_citation: N]` 前缀剥掉、保留其后的 `[[N]](url)` 链接,`LEGACY_CITATION_RE` 直接删除旧式 `[citation: N]` 标记。导出时 `run_jiuwen_workflow` 将报告写成 Markdown,再调用 `convert_md_to_html` 和 `convert_md_to_docx`,并把三个文件移入 `SKILL_ROOT/output/reports`;该 try 块仅捕获 OSError,此时只在当前目录重写 Markdown 文件作为回退。 + +Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py:L36–L39](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py#L36-L39), [jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py:L98–L127](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/openJiuwen-DeepSearch/scripts/main.py#L98-L127) + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-arxiv-visual-extraction.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-arxiv-visual-extraction.md index b170bde0..e67bdff2 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-arxiv-visual-extraction.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-depth-arxiv-visual-extraction.md @@ -4,7 +4,7 @@ created: 2026-10-06 updated: 2026-10-06 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L1410-L1465, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L200-L246, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L55-L56, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L96-L112, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L1370-L1370, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L1298-L1299, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L1224-L1232, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L1330-L1333, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L891-L901, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L1259-L1266] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L1410-L1465, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L200-L246, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L55-L56, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L96-L112, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L1370-L1370, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L1298-L1299, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L1224-L1232, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L1330-L1333, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L891-L901, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py:L1259-L1266, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/workflows/acquire-visuals.md:L44-L52, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/workflows/acquire-visuals.md:L64-L73, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py:L128-L174, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py:L231-L253] feature: "arxiv-visual-extraction" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/extract_arxiv_visuals_v2_2.py"] @@ -69,3 +69,14 @@ For each candidate the script unions region and caption bboxes and tries render_ + + +**已文档化的 paper-figure 手工复核流程(prepare→看 contact sheet→approve→used),未执行** +文档中的人工验收步骤(本轮未执行): + +工作流文档规定了具体操作:先运行 `python3 ../scripts/prepare_evidence.py .` 走 `paper-figure` 路由(prepare_paper 调用 extract_arxiv_visuals_v2_2.py 并解析 manifest),再查看 `analysis/evidence-contact-sheet.jpg` 或论文专属 contact sheet 后执行 `--approve `,素材加入幻灯片后执行 `--used `;预期结果是文件视觉素材经 `review.approved` 后状态变为 ready/used,自动选择不唯一时状态转为 needs-manual 并保留 manifest 与 contact sheet 供人工判断。该流程是文档化手工确认视觉相关性与可读性,不是裁图正确性的自动化断言;NOT EXECUTED(本次未运行)。 + +来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/workflows/acquire-visuals.md:L44–L52](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/workflows/acquire-visuals.md#L44-L52), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/workflows/acquire-visuals.md:L64–L73](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/workflows/acquire-visuals.md#L64-L73), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py:L128–L174](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py#L128-L174), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py:L231–L253](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/prepare_evidence.py#L231-L253) + + + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-huawei-maas-apikey-creation.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-huawei-maas-apikey-creation.md index 658b502d..a70b9299 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-huawei-maas-apikey-creation.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-huawei-maas-apikey-creation.md @@ -1,10 +1,10 @@ --- title: "华为云 MaaS API Key 自动创建与捕获(auto_create_apikey)" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py:L207-L238, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py:L363-L406, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py:L240-L331, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/lib/huawei_selectors.py:L34-L66, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py:L356-L370, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py:L380-L404, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py:L228-L232, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/lib/huawei_selectors.py:L93-L108, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py:L81-L83, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py:L250-L260, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py:L315-L330, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py:L399-L406] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py:L207-L238, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py:L363-L406, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py:L240-L331, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/lib/huawei_selectors.py:L34-L66, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py:L356-L370, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py:L380-L404, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py:L228-L232, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/lib/huawei_selectors.py:L93-L108, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py:L81-L83, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py:L250-L260, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py:L315-L330, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py:L399-L406, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py:L341-L370] feature: "huawei-maas-apikey-creation" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py", "jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/lib/huawei_selectors.py"] @@ -44,3 +44,11 @@ Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-ma Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py:L81–L83](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py#L81-L83), [jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py:L250–L260](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py#L250-L260), [jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py:L315–L330](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py#L315-L330), [jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py:L399–L406](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py#L399-L406) + + +**自动创建并捕获 API Key 的端到端流程** + +脚本通过 CDP 接入用户已登录的浏览器,在华为云 MaaS 控制台的 API Key 管理页自动完成整条链路:点击"创建 API Key"、填写自动加了时间戳后缀的标签与描述、best-effort 选择"全部"权限、点击"确定"提交,随后在 14 秒轮询窗口内检测结果弹窗(copy-key-modal)以及欠费、未实名认证两类错误提示并返回对应 stage。成功时从结果弹窗提取完整 Key,经 `_is_plausible_key`(长度 ≥30 且非纯数字)校验后随 `make_success` 返回,并 best-effort 点击复制按钮和"我已保存,确认关闭"关闭弹窗。 + +Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py:L240–L331](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py#L240-L331), [jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py:L341–L370](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py#L341-L370), [jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py:L81–L83](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_create_apikey.py#L81-L83) + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-huawei-realname-account-check.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-huawei-realname-account-check.md index bd0f9ff1..ce0e04b9 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-huawei-realname-account-check.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-huawei-realname-account-check.md @@ -1,10 +1,10 @@ --- title: "check_account — 华为云账号实名认证状态检测脚本" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/check_account.py:L3-L17, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/check_account.py:L56-L96, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/check_account.py:L110-L128, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/check_account.py:L90-L102, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/lib/huawei_selectors.py:L558-L605, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/check_account.py:L50-L96, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/lib/huawei_selectors.py:L561-L605, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/check_account.py:L50-L82, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/check_account.py:L14-L17] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/check_account.py:L3-L17, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/check_account.py:L56-L96, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/check_account.py:L110-L128, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/check_account.py:L90-L102, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/lib/huawei_selectors.py:L558-L605, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/check_account.py:L50-L96, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/lib/huawei_selectors.py:L561-L605, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/check_account.py:L50-L82, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/check_account.py:L14-L17, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/lib/huawei_selectors.py:L569-L605, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/check_account.py:L57-L64, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/check_account.py:L126-L128] feature: "huawei-realname-account-check" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/check_account.py", "jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/lib/huawei_selectors.py"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/check_account.py", "jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/lib/huawei_selectors.py"] @@ -54,3 +54,11 @@ Inference / 设计推断(非作者历史意图): Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/lib/huawei_selectors.py:L561–L605](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/lib/huawei_selectors.py#L561-L605), [jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/check_account.py:L50–L82](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/check_account.py#L50-L82), [jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/check_account.py:L14–L17](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/check_account.py#L14-L17) + + +**验证形式:运行时防护与超时兜底(非自动化测试)** + +所示文件中未包含自动化测试入口;验证以脚本内的运行时防护(runtime guards)形式存在。`detect_realname_status` 以 deadline 循环(`time.time() + timeout_ms/1000`)反复尝试 JS 变量与 DOM 提醒条两级检测,每轮末 `sleep(0.5)`;超时仍未判定时 emit 一条提示并兜底返回 False(视为未认证)。`check_account` 将浏览器连接失败与检测阶段的异常都转为 `make_failure` 结果而非向上抛出,`main` 依据 `result["ok"]` 决定退出码 0/1。 + +Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/lib/huawei_selectors.py:L569–L605](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/lib/huawei_selectors.py#L569-L605), [jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/check_account.py:L57–L64](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/check_account.py#L57-L64), [jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/check_account.py:L126–L128](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/check_account.py#L126-L128) + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-local-doc-ocr-offline.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-local-doc-ocr-offline.md index d5fb50eb..9b9b9210 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-local-doc-ocr-offline.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-local-doc-ocr-offline.md @@ -1,10 +1,10 @@ --- title: "local-doc-ocr:本地离线 OCR 管线(RapidOCR:PDF/图片 → Markdown)" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py:L129-L158, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/write_ocr_md.py:L4-L17, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/setup.py:L41-L55, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py:L112-L123, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py:L175-L189, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py:L231-L234, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/pdf_to_images.py:L100-L108, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/write_ocr_md.py:L46-L47, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py:L93-L109, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py:L169-L189, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py:L22-L32] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py:L129-L158, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/write_ocr_md.py:L4-L17, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/setup.py:L41-L55, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py:L112-L123, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py:L175-L189, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py:L231-L234, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/pdf_to_images.py:L100-L108, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/write_ocr_md.py:L46-L47, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py:L93-L109, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py:L169-L189, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py:L22-L32, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py:L206-L218, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/preprocess_img.py:L35-L58, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py:L129-L145, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py:L160-L167, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py:L224-L229, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/pdf_to_images.py:L74-L92] feature: "local-doc-ocr-offline" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py", "jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/write_ocr_md.py", "jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/preprocess_img.py", "jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/pdf_to_images.py", "jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/setup.py"] @@ -44,3 +44,19 @@ ocr_offline.py 是主入口:collect_images 把输入分类为 PDF、单图/图 Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py:L93–L109](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py#L93-L109), [jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py:L169–L189](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py#L169-L189), [jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/setup.py:L41–L55](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/setup.py#L41-L55), [jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py:L22–L32](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py#L22-L32) + + +**离线优先与容错取舍** + +隐私优先:识别用本地 ONNX 引擎 RapidOCR,输出显式声明「不联网、不上传」;代价是首次依赖缺失时需联网装一次白名单包(setup.py 仅在 find_spec 检出缺失时才安装,依赖齐则直接返回就绪)。识别质量取舍:RapidOCR 对手写/印章/严重倾斜较弱,脚本在空页建议和结尾警告中明确引导改走多模态读图路线复核,而不是自行调参兜底。预处理(preprocess_img.preprocess)仅对 EXIF 转置、倾斜校正、锐化各步分别 try/except 吞错跳过,灰度转换等步骤异常仍会向上传播,并非整体降级。 + +Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/setup.py:L41–L55](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/setup.py#L41-L55), [jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py:L206–L218](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py#L206-L218), [jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/preprocess_img.py:L35–L58](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/preprocess_img.py#L35-L58) + + + +**CLI Options and Output-Path Resolution** + +The ocr_offline.py CLI has no external configuration files or environment variables; all configuration is provided through command-line arguments: `-o/--out` (default None), `-d/--dpi` (default 300), `--no-preprocess` (default off), `--start-page`/`--end-page` (default None, 1-based; `render_pdf` applies one-sided bounds via `s = max(1, start_page or 1)` and `e = min(n, end_page or n)`, so either bound can be set alone), and `--boxes-json` (default off). Output-path resolution is two-step and differs by input type: when `-o` is omitted, directory inputs write `_OCR.md` inside the input directory itself (L164–L165), while file inputs write it next to the input (L166–L167); the boxes JSON is always derived from the resolved Markdown path as `os.path.splitext(out_md)[0] + "_boxes.json"` (L224–L225), so a custom `-o` such as `out.md` yields `out_boxes.json`, not `_OCR_boxes.json`. The sibling pdf_to_images.py mirrors these knobs (`-d` 300, `-p/-n` page bounds, `-o` output directory defaulting to a `_pages` folder beside the PDF) plus `--preprocess`, `-b`, and `-t/--tiles` (default 0). + +Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py:L129–L145](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py#L129-L145), [jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py:L160–L167](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py#L160-L167), [jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py:L224–L229](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/ocr_offline.py#L224-L229), [jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/pdf_to_images.py:L74–L92](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/local-doc-ocr/scripts/pdf_to_images.py#L74-L92) + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-maas-auto-open-models.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-maas-auto-open-models.md index 1238b791..f1b39587 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-maas-auto-open-models.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-maas-auto-open-models.md @@ -1,10 +1,10 @@ --- title: "华为云 MaaS 预置服务批量开通脚本 auto_open_model.py" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L508-L527, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L750-L812, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L770-L810, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L655-L660, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L556-L606, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L613-L627, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L686-L720, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L655-L684, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L686-L727, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L732-L738, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L808-L812] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L508-L527, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L750-L812, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L770-L810, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L655-L660, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L556-L606, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L613-L627, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L686-L720, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L655-L684, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L686-L727, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L732-L738, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L808-L812, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L514-L519, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L686-L705] feature: "maas-auto-open-models" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py"] @@ -44,3 +44,13 @@ Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-ma Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L655–L684](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py#L655-L684), [jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L686–L727](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py#L686-L727), [jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L732–L738](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py#L732-L738), [jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L808–L812](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py#L808-L812) + + +**批量入口策略:文档化动机与启发式完成判定** + +Inference / 设计推断(非作者历史意图): + +docstring(L516–L518)明确记录的取舍是:只搜索第一个可开通的模型并借其批量订阅弹窗一次性勾选全部目标、点击一次"一键开通",以避免逐模型搜索+开通的冗余操作;代价是 pending 模型不再做逐项的类型/入口检查,未能在弹窗中勾选的模型只 emit 警告并在成功分支事后补记失败。完成判定(L655–L684)采用启发式轮询——订阅按钮消失、弹窗不可见或成功提示任一命中即算成功——并因"弹窗关闭 ≠ 开通生效"(L687 注释)在成功后重载表格逐模型回读"已开通"状态作为最终验证(此为代码行为分析,非文档声明的动机)。 + +Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L514–L519](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py#L514-L519), [jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L655–L684](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py#L655-L684), [jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py:L686–L705](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/huawei-cloud-maas-setup/scripts/auto_open_model.py#L686-L705) + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-plugin-package-initializer.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-plugin-package-initializer.md index 57ca35d5..d34a5061 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-plugin-package-initializer.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-plugin-package-initializer.md @@ -1,10 +1,10 @@ --- title: "plugin-creator 插件包脚手架初始化(init_plugin.py)" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L91-L103, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L186-L191, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L141-L162, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L1-L18, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L184-L202, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L91-L107, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L129-L147, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L150-L165, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L150-L162, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L196-L202] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L91-L103, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L186-L191, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L141-L162, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L1-L18, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L184-L202, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L91-L107, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L129-L147, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L150-L165, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L150-L162, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L196-L202, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L21-L41, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L114-L126, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L164-L181] feature: "plugin-package-initializer" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py"] @@ -54,3 +54,11 @@ Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/plugin-creator/ Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L129–L147](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py#L129-L147), [jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L150–L162](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py#L150-L162), [jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L196–L202](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py#L196-L202) + + +**脚手架生成:manifest.json 与 README.md 模板** + +init_package() 在目标目录下生成两个骨架文件:`manifest.json`(由 MANIFEST_TEMPLATE 填入包名 id,version 固定 "1.0.0"、package_type "plugin"、source "local")和 `README.md`(标题由包名 kebab-case 转为 Title Case)。manifest 中 display_name、display_description、default_init_input、tags、quick_inputs 为中英双语占位;`description`(L26)是单个中文占位串,与双语字段区分。生成后输出提示 [TODO] 占位需在下一步填写。名称式输入额外经 _assert_package_id_available 检查与 local、built_in 两个既有包目录的 id 冲突:local 冲突提示可重命名或删除旧包后重试,built_in 冲突则要求换名。 + +Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L21–L41](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py#L21-L41), [jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L114–L126](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py#L114-L126), [jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py:L164–L181](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/init_plugin.py#L164-L181) + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-plugin-package-layered-validator.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-plugin-package-layered-validator.md index b16e548b..a119a052 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-plugin-package-layered-validator.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-plugin-package-layered-validator.md @@ -1,10 +1,10 @@ --- title: "plugin-creator 插件包分层校验器(validate_plugin.py L0/L1/L2)" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py:L1-L15, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py:L955-L968, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin_hot_load_worker.py:L136-L217, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py:L157-L170, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py:L34-L44, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin_hot_load_worker.py:L100-L133, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin_hot_load_worker.py:L288-L306, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py:L823-L891, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py:L230-L246, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py:L258-L266, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py:L522-L543, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py:L648-L652, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py:L806-L891, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py:L513-L543, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py:L782-L798] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py:L1-L15, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py:L955-L968, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin_hot_load_worker.py:L136-L217, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py:L157-L170, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py:L34-L44, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin_hot_load_worker.py:L100-L133, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin_hot_load_worker.py:L288-L306, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py:L823-L891, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py:L230-L246, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py:L258-L266, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py:L522-L543, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py:L648-L652, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py:L806-L891, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py:L513-L543, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py:L782-L798, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py:L933-L950, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py:L157-L182, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py:L906-L927, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py:L955-L971] feature: "plugin-package-layered-validator" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py", "jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin_hot_load_worker.py"] @@ -54,3 +54,11 @@ Inference / 设计推断(非作者历史意图): Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py:L806–L891](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py#L806-L891), [jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin_hot_load_worker.py:L136–L217](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin_hot_load_worker.py#L136-L217), [jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py:L513–L543](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py#L513-L543), [jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py:L782–L798](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py#L782-L798) + + +**CLI 入口与退出码契约** + +公开入口是命令行 `validate_plugin.py [--no-hot-load]`:target 既可以是包目录路径,也可以是 `local/` 下的 plugin-name——resolve_pkg 先按目录解析,失败时回退到 `/agent/workspace/plugins/plugin_packages/local/`,都找不到则向 stdout 写 Error 并返回 1(validate_plugin.py:937-950, 173-182)。退出码 0 仅当 L0/L1/L2 三层状态全为 PASS(含被跳过的 L2 不算 PASS),否则为 1(validate_plugin.py:970-971);`--no-hot-load` 或 L0/L1 有错时 L2 记为 SKIP(validate_plugin.py:956-961)。汇总的 RESULT 行按优先级输出:任一层有 errors 时为 FAIL;仅当 L0/L1 无错且 L2 无错但状态为 SKIP 时输出 RESULT: PARTIAL(validate_plugin.py:906-927)。 + +Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py:L933–L950](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py#L933-L950), [jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py:L157–L182](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py#L157-L182), [jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py:L906–L927](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py#L906-L927), [jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py:L955–L971](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/plugin-creator/scripts/validate_plugin.py#L955-L971) + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-ppt-deck-finalize.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-ppt-deck-finalize.md index 30a5b78e..e519c816 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-ppt-deck-finalize.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-ppt-deck-finalize.md @@ -1,10 +1,10 @@ --- title: "一键成片流水线与质量门禁(finalize_deck.py)" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py:L100-L115, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py:L192-L197, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py:L104-L115, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py:L123-L130, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/merge_slides.py:L439-L449, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/merge_slides.py:L85-L122, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/merge_slides.py:L168-L212, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/fill_cover.py:L145-L181, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/make_blank_template.py:L11-L29, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py:L132-L163, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py:L60-L66, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py:L165-L188] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py:L100-L115, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py:L192-L197, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py:L104-L115, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py:L123-L130, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/merge_slides.py:L439-L449, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/merge_slides.py:L85-L122, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/merge_slides.py:L168-L212, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/fill_cover.py:L145-L181, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/make_blank_template.py:L11-L29, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py:L132-L163, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py:L60-L66, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py:L165-L188, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py:L88-L97] feature: "ppt-deck-finalize" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py", "jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/make_blank_template.py", "jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/fill_cover.py", "jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/opc/prune.py", "jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/merge_slides.py"] @@ -44,3 +44,19 @@ finalize_deck.py is a process-level orchestrator: it unpacks the template and th Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py:L132–L163](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py#L132-L163), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py:L60–L66](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py#L60-L66), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py:L165–L188](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py#L165-L188) + + +**模板继承换统一版式,门禁以“打包后校验”兜底** + +默认 `--source-layout-mode template` 将生成内容页重链到模板版式,收益是继承模板的母版/版式结构、代价是放弃 PptxGenJS 自带的设计部件(merge_slides.py 文档说明 `source` 模式仅留给刻意携带自有 layouts/masters/themes 的旧deck)。为兜住合并可能悄悄丢结构的风险,finalize_deck 在打包后做硬门禁:母版/版式数量少于模板基线(仅在 template 模式下检查,基线从模板自身读出而非硬编码)即抛 FinalizeError;封面标题门禁则无条件执行,因为模板 ctrTitle 出厂为空、漏填的封面看起来完工实则无题。 + +Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py:L165–L188](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py#L165-L188), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/merge_slides.py:L439–L449](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/merge_slides.py#L439-L449) + + + +**打包后运行时质量门禁(非自动化测试)** + +所示的 finalize_deck.py 没有测试入口;其可验证性体现为每次运行时在打包后执行的硬门禁(runtime guard,非测试执行)。其一为母版继承检查:用 digest() 比较 [输出] 与模板的母版/版式数量,仅当 --source-layout-mode 为 template 且输出的母版数或版式数少于模板基线时抛 FinalizeError——不比较幻灯片张数,基线从所 supplied 模板读出而非硬编码。其二为封面标题检查:cover_title_filled() 遍历幻灯片,对首个含 type="ctrTitle" 的形状提取 文本并要求非空;若整副牌没有 ctrTitle 占位符(如 --order 不含 t1)则直接返回 True 放行。失败经 main() 转为带信息的 SystemExit 退出。 + +Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py:L165–L188](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py#L165-L188), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py:L88–L97](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py#L88-L97), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py:L192–L197](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/finalize_deck.py#L192-L197) + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-ppt-execution-lock-validator.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-ppt-execution-lock-validator.md index ec5a18a0..3d2a9cf1 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-ppt-execution-lock-validator.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-ppt-execution-lock-validator.md @@ -1,10 +1,10 @@ --- title: "PPT 执行锁(execution-lock.json)语义校验器" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-evidence-plan.js:L106-L133, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L16-L19, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L21-L23, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L182-L199, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-evidence-plan.js:L26-L36, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-evidence-plan.js:L115-L124, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L129-L179, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L235-L246, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L11-L19, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L56-L76, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L98-L101, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-evidence-plan.js:L96-L101] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-evidence-plan.js:L106-L133, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L16-L19, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L21-L23, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L182-L199, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-evidence-plan.js:L26-L36, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-evidence-plan.js:L115-L124, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L129-L179, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L235-L246, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L11-L19, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L56-L76, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L98-L101, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-evidence-plan.js:L96-L101, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L48-L54, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L249-L252] feature: "ppt-execution-lock-validator" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js", "jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-evidence-plan.js"] @@ -44,3 +44,11 @@ Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/sc Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L11–L19](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js#L11-L19), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L56–L76](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js#L56-L76), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L98–L101](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js#L98-L101), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-evidence-plan.js:L96–L101](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-evidence-plan.js#L96-L101) + + +**CLI 入口与退出码契约** + +validate-execution-lock.js 是可直接执行的 Node CLI:用法为 `node validate-execution-lock.js [--phase design|generate|deliver]`,phase 缺省为 design;缺少位置参数或 phase 不在三个合法值内时打印 usage 到 stderr 并以退出码 2 结束。锁文件无法 JSON 解析时打印 [ERROR] 并退出 1。校验器通过 error()/warn() 帮助函数把消息收集到 errors/warnings 数组,末尾逐条打印 [ERROR]/[WARN] 加一行汇总(如 `execution-lock: N error(s), M warning(s), phase=...`),并按 errors 是否非空决定退出 1 或 0。 + +Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L11–L19](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js#L11-L19), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L48–L54](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js#L48-L54), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js:L249–L252](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/validate-execution-lock.js#L249-L252) + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-ppt-figure-panel-layout.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-ppt-figure-panel-layout.md index dd928c07..151ef717 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-ppt-figure-panel-layout.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-ppt-figure-panel-layout.md @@ -1,10 +1,10 @@ --- title: "PPT 图表面板布局引擎(figure-panel.js)" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L82-L104, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L34-L37, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L1-L8, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L82-L92, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L10-L21, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L93-L98, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L23-L41] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L82-L104, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L34-L37, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L1-L8, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L82-L92, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L10-L21, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L93-L98, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L23-L41, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L42-L57, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L82-L98, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L26-L37, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L82-L87] feature: "ppt-figure-panel-layout" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js"] @@ -44,3 +44,19 @@ L6–L7 注释明确说明:slides.js 顺序调用组件,因此本文件刻 Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L1–L8](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js#L1-L8), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L23–L41](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js#L23-L41) + + +**支持的布局行为** + +引擎按宽高比分行:ar ≥ WIDE_AR(2.5) 的宽图独占一行,较方的图与相邻的方图两两并排(L44–L48)。行内按可用高度统一缩放(scale ≤ 1,仅缩图片,标签与间距保持绝对尺寸),整块内容在 bounds 内垂直居中,行内图片在行高中垂直居中(L55–L57、L88、L68)。渲染时每张图通过 slide.addImage 原样贴入(无边框无填充),若 figure 带 label 则在其下方绘制居中、fit:shrink 的中文说明文字(L90–L98)。 + +Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L42–L57](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js#L42-L57), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L82–L98](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js#L82-L98) + + + +**验证入口:运行时守卫(非测试)** + +所示文件不含任何测试入口点或断言辅助函数,唯一的验证机制是 `pngSize` 内的运行时守卫(runtime guard,属于检查而非测试执行):读取文件前 24 字节后,先校验 PNG 签名(`0x89504e47`),再校验第 12–16 字节为 `IHDR`,任一不满足即抛出包含文件路径的 Error(如 `not a PNG: `)。这两个守卫在 `renderFigurePanel` 读取每张图尺寸时被调用,是渲染路径上实际执行的输入校验。 + +Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L26–L37](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js#L26-L37), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js:L82–L87](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/figure-panel.js#L82-L87) + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-pptx-structural-audit.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-pptx-structural-audit.md index 390b22fd..c89deb4b 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-pptx-structural-audit.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-pptx-structural-audit.md @@ -1,10 +1,10 @@ --- title: "PPTX 结构与可读性审计脚本(audit_pptx.py 及配套 QA 脚本)" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L511-L534, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/qa_density.py:L9-L18, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/qa_geometry.py:L459-L482, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L494-L534, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/qa_density.py:L67-L111, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L303-L313, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/qa_geometry.py:L1-L13, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/qa_geometry.py:L229-L253, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/qa_geometry.py:L442-L452, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L303-L336, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L344-L381, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/qa_geometry.py:L229-L279] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L511-L534, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/qa_density.py:L9-L18, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/qa_geometry.py:L459-L482, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L494-L534, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/qa_density.py:L67-L111, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L303-L313, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/qa_geometry.py:L1-L13, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/qa_geometry.py:L229-L253, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/qa_geometry.py:L442-L452, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L303-L336, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L344-L381, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/qa_geometry.py:L229-L279, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L221-L246, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L133-L143, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/qa_density.py:L1-L30, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L494-L509, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L415-L426, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L450-L467] feature: "pptx-structural-audit" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py", "jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/qa_density.py", "jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/qa_geometry.py"] @@ -44,3 +44,19 @@ audit_pptx.py 检查必需包部件缺失、幻灯片关系指向的部件存在 Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L303–L336](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py#L303-L336), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L344–L381](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py#L344-L381), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/qa_geometry.py:L229–L279](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/qa_geometry.py#L229-L279) + + +**页脚豁免与显式字号检查的取舍** + +body-min 字号警告有意排除页脚区(画布高度 90% 以下的形状不计入 body_font_sizes),因为页脚 chrome 本就约 7pt、官方母版页脚为 9.74pt,计入会对每页每份 deck 都告警,反而让人忽略警告列;代价是该警告不覆盖页脚内容的可读性。另一个限制是字号检查只收集幻灯片 XML 中带显式 sz 属性的 rPr/defRPr/endParaRPr 值,不解析从母版/版式继承的字号,因此绝对下限仅对页面上显式声明的字号生效。qa_density.py 的密度下限则是写死的常量(FLOOR_HARD=300、FLOOR_WARN=400),按真实内部 deck 校准(内容页 400-700 可视字符,中位约 480),不暴露为 CLI 选项。 + +Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L221–L246](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py#L221-L246), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L133–L143](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py#L133-L143), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/qa_density.py:L1–L30](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/qa_density.py#L1-L30) + + + +**CLI 字号阈值默认值与执行锁的优先级** + +audit_pptx.py 的三个字号阈值均为 CLI 选项而非配置文件:--title-min-font 默认 24、--body-min-font 默认 10、--absolute-min-font 默认 7(type=float)。当传入 --lock 且某页在锁中映射为 standard-content 角色时,标题下限改用锁内 deck.typography_policy.title_min_pt(缺省回退到 CLI 值),总结条颜色用锁内 brand.summary_banner.fill(回退 4472C4);该标题检查只作用于这些锁映射的 standard-content 页,TOC 角色页另有独立的 TOC_MIN_TIER_PT=12 常量下限(乘 compat_scale 换算)。 + +Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L494–L509](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py#L494-L509), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L415–L426](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py#L415-L426), [jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py:L450–L467](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/ppt-creation/scripts/audit_pptx.py#L450-L467) + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-rsi-dataset-folder-check.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-rsi-dataset-folder-check.md index fa770526..5e4cfe0b 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-rsi-dataset-folder-check.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-rsi-dataset-folder-check.md @@ -1,10 +1,10 @@ --- title: "RSI 数据集任务文件夹完整性预检 check_folder.py" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L67-L83, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L210-L218, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L22-L45, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L151-L159, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L161-L178, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L2-L8, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L19-L20, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L195-L214] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L67-L83, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L210-L218, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L22-L45, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L151-L159, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L161-L178, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L2-L8, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L19-L20, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L195-L214, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L115-L125] feature: "rsi-dataset-folder-check" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py"] @@ -46,3 +46,11 @@ Inference / 设计推断(非作者历史意图): Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L2–L8](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py#L2-L8), [jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L195–L214](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py#L195-L214) + + +**支持的检查行为** + +除键集与数值下限外,脚本实现了跨文件一致性检查:`artifact_path` 必须按 seed 规模取值——单文件 seed 指向 `seed/`,多文件树则必须是 `seed` 本身,注释说明 provider 只加载 artifact_path 名下的内容(L115–L125);`prompts/mutation.md` 若存在则必须包含 `${reply_format}` 占位符(L186–L188)。另一特性是启发式警告通道:当 Python evaluator 的 script 含 `except` 却不含 `traceback` 时,仅发出警告而非记入 problems;注释明确这是脚本无法测试的运行时"smell"——探针运行的受损副本若抛异常且 `error` 报告不含位置信息,该文件夹才会被拒(PROBE_REFUSED),退出码不受 warnings 影响(L195–L214)。 + +Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L115–L125](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py#L115-L125), [jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py:L195–L214](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/rsi-program-dataset-creator/scripts/check_folder.py#L195-L214) + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-skill-page-scrape-blocks.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-skill-page-scrape-blocks.md index db816064..be1a6ed6 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-skill-page-scrape-blocks.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-skill-page-scrape-blocks.md @@ -1,10 +1,10 @@ --- title: "skill-omni-creation 网页抓取到统一 Stage01 Blocks(scrape_page)" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L375-L402, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L703-L713, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L820-L876, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L885-L911, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L922-L922, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L955-L966, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/common.py:L52-L57, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L860-L876, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/download_images.py:L94-L95, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/download_images.py:L134-L158, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/print_blocks.py:L126-L138, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L895-L911, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/download_images.py:L109-L115, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/environment_gate.py:L418-L424, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/download_images.py:L27-L31, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L94-L108, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L542-L551, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/environment_gate.py:L141-L168] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L375-L402, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L703-L713, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L820-L876, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L885-L911, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L922-L922, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L955-L966, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/common.py:L52-L57, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L860-L876, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/download_images.py:L94-L95, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/download_images.py:L134-L158, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/print_blocks.py:L126-L138, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L895-L911, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/download_images.py:L109-L115, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/environment_gate.py:L418-L424, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/download_images.py:L27-L31, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L94-L108, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L542-L551, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/environment_gate.py:L141-L168, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L353-L370, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L103-L108, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L502-L526, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L671-L689] feature: "skill-page-scrape-blocks" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py", "jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/print_blocks.py", "jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/common.py", "jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/download_images.py", "jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/environment_gate.py"] @@ -52,3 +52,11 @@ Stage01 的体量由 scrape_page.py 顶部的模块常量控制:STAGE01_MAX_BL Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L94–L108](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py#L94-L108), [jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L542–L551](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py#L542-L551), [jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/environment_gate.py:L141–L168](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/environment_gate.py#L141-L168), [jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/environment_gate.py:L418–L424](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/environment_gate.py#L418-L424) + + +**JS 叶子文本容器的取舍与 stage01 单点有界化的取舍** + +为了捕获用 div/section/article 而非语义标签渲染的 JS 文本,_is_leaf_js_text_container 仅接受文本长度严格大于 15 且不超过 5000 字符的包装元素;当任一后代 div/section/article 的文本超过 15 字符时放弃该容器,代码注释说明这是为了优先取最深层有用包装、避免同一段 JS 文本重复输出——即以可能漏掉部分非语义文本为代价换取去重和噪声控制。体量控制方面,stage01 被设计为唯一对全页做有界化的环节(420 块 / 60 000 文本字符 / 90 000 序列化字符目标),stage02/03 保持原行为消费有界后的块;超限时按 heading/image 优先级做全局均匀采样并对文本做加权水填充截断。90 000 序列化上限是尽力而非硬保证:保留块数减到 1 后循环停止,且 serialized_chars 字段是在测量之后才附加进 payload 的。 + +Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L353–L370](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py#L353-L370), [jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L103–L108](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py#L103-L108), [jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L502–L526](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py#L502-L526), [jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py:L671–L689](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-omni-creation/scripts/scrape_page.py#L671-L689) + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-sop-structure-extraction.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-sop-structure-extraction.md index a0713963..e57c474d 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-sop-structure-extraction.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-sop-structure-extraction.md @@ -1,10 +1,10 @@ --- title: "SOP 结构化抽取(parse_sop_raw_text / parse_sop_file)" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/__init__.py:L9-L21, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L257-L273, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L394-L427, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L275-L306, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L310-L341, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_chunk_merge.py:L478-L560, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L246-L254, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L279-L304, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_chunk_merge.py:L459-L468, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L315-L341, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_chunk_merge.py:L403-L456, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_chunk_merge.py:L537-L557, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L343-L347, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L371-L389, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L365-L369] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/__init__.py:L9-L21, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L257-L273, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L394-L427, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L275-L306, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L310-L341, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_chunk_merge.py:L478-L560, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L246-L254, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L279-L304, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_chunk_merge.py:L459-L468, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L315-L341, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_chunk_merge.py:L403-L456, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_chunk_merge.py:L537-L557, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L343-L347, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L371-L389, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L365-L369, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L430-L455, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_fallback.py:L1-L13, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_fallback.py:L360-L378, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_fallback.py:L416-L426] feature: "sop-structure-extraction" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py", "jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_chunk_merge.py", "jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_fallback.py", "jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/__init__.py", "jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/models.py"] @@ -52,3 +52,11 @@ Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-ent Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L343–L347](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py#L343-L347), [jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L371–L389](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py#L371-L389), [jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L365–L369](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py#L365-L369) + + +**功能:文档抽取与无文档时的意图兜底** + +该特性提供两条功能路径。其一,`parse_sop_file` 从文件加载纯文本:优先用 agent-core 的 `AutoFileParser`(支持时解析文档并拼接各 chunk 文本),当解析器不可用、抛错或返回空结果时回退为直接读取,且直接读取仅接受 `.md/.txt/.json/.yaml/.yml` 后缀,其他格式抛 `ValueError` 提示安装 agent-core;加载后的文本交由 `parse_sop_raw_text` 做 LLM 结构化抽取(单发或分块),全文始终保留在 `SOPStructure.raw_text`。其二,当会话中没有任何 SOP 文档时,`sop_fallback` 提供意图兜底:默认应在运行时能调用模型时就传入 `invoke_llm_json`(`build_intent_fallback_sop` 先确定性构建骨架再调用 `enrich_fallback_sop_with_llm` 精修),只有系统无法运行 LLM(测试、离线、宿主未接线、策略限制)时才传 `None` 或单独使用 `build_fallback_sop_structure`;兜底产物带与 LLM 抽取相同的字段,并在 meta 中标记 `fallback_sop`/`fallback_reason`,enrich 失败或空响应时原样返回输入结构。 + +Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py:L430–L455](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_parser.py#L430-L455), [jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_fallback.py:L1–L13](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_fallback.py#L1-L13), [jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_fallback.py:L360–L378](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_fallback.py#L360-L378), [jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_fallback.py:L416–L426](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/skill-gen-4-enterprise-doc/scripts/skill_gen/sop_fallback.py#L416-L426) + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-xlsx-add-computed-column.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-xlsx-add-computed-column.md index 4b8f2fe8..dba00361 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-xlsx-add-computed-column.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-xlsx-add-computed-column.md @@ -1,10 +1,10 @@ --- title: "XLSX Computed Column Adder (xlsx_add_column.py)" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L51-L65, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L3-L13, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L1-L20, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L52-L65, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L74-L78, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L80-L86, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L89-L102, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L104-L109, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L67-L78, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L89-L95, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L111-L115] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L51-L65, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L3-L13, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L1-L20, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L52-L65, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L74-L78, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L80-L86, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L89-L102, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L104-L109, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L67-L78, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L89-L95, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L111-L115, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L3-L6, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L28-L37] feature: "xlsx-add-computed-column" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py"] @@ -52,3 +52,11 @@ Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xl Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L3–L13](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py#L3-L13), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L67–L78](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py#L67-L78), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L89–L95](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py#L89-L95), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L111–L115](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py#L111-L115) + + +**设计取舍:直接编辑解包 XML 与边框样式改写** + +脚本选择在 xlsx_unpack.py 产出的解包目录内直接解析并原地改写工作表 XML(docstring 自述为“零格式损失:现有单元格不被触碰”),代价是流程依赖 unpack/edit/repack 三段式链路,而非单工具完成。另一个可见限制:--border-row 对该行每个已有单元格重写样式索引时,只通过 numfmt_of 读取并保留原样式的 numFmtId(L104–L109、L28–L37),所示代码中未体现保留 xf 的其他属性(如字体、填充)。 + +Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L3–L6](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py#L3-L6), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L104–L109](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py#L104-L109), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py:L28–L37](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_add_column.py#L28-L37) + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-xlsx-insert-row.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-xlsx-insert-row.md index 2cc98375..2b62f897 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-xlsx-insert-row.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-xlsx-insert-row.md @@ -1,10 +1,10 @@ --- title: "XLSX Row Insert with Range Extension(jiuwenswarm skills/xlsx 脚本)" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py:L57-L77, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L66-L89, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py:L3-L7, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L52-L60, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py:L96-L113, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L5-L20, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_shift_rows.py:L9-L12, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L66-L85, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py:L154-L169, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L14-L20, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py:L179-L196, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py:L142-L157, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L5-L7] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py:L57-L77, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L66-L89, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py:L3-L7, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L52-L60, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py:L96-L113, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L5-L20, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_shift_rows.py:L9-L12, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L66-L85, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py:L154-L169, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L14-L20, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py:L179-L196, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py:L142-L157, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L5-L7, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L49-L58, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L60-L64, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L89-L95, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py:L65-L77] feature: "xlsx-insert-row" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py", "jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_shift_rows.py", "jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py"] @@ -54,3 +54,11 @@ Inference / 设计推断(非作者历史意图): Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py:L3–L7](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py#L3-L7), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py:L142–L157](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py#L142-L157), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_shift_rows.py:L9–L12](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_shift_rows.py#L9-L12), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L5–L7](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py#L5-L7) + + +**xlsx_insert_row.py CLI 契约** + +入口是命令行脚本 `xlsx_insert_row.py`(`main()` 经 `sys.exit(main())` 调用,成功返回 0 并打印确认行)。调用契约:位置参数 `workdir`(解包的工作簿目录)为必需;`--at`(int,必需)指定新行占据的 1-based 行号;可选 `--sheet`、`--text/--values/--formula`(COL=VALUE 对,缺省空列表)与 `--copy-style-from`(int,可选)。`--sheet` 缺省时取 workbook.xml 的第一个表;找不到表或关系时 `resolve_worksheet` 以 `SystemExit` 终止并带错误消息。输入的 COL=VALUE 对缺少 `=` 时由 `parse_pairs` 以 SystemExit 拒绝。文档要求编辑后用 xlsx_pack.py 重打包。 + +Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L49–L58](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py#L49-L58), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L60–L64](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py#L60-L64), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py:L89–L95](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_insert_row.py#L89-L95), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py:L65–L77](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/_xlsx_common.py#L65-L77) + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/feature-xlsx-reader-structural-diff.md b/knowledge/repos/jiuwenswarm/components/config-resources/feature-xlsx-reader-structural-diff.md index 4ea07f23..74860efa 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/feature-xlsx-reader-structural-diff.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/feature-xlsx-reader-structural-diff.md @@ -1,10 +1,10 @@ --- title: "XLSX 只读结构读取器与编辑损伤差分(xlsx_reader.py)" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L32-L50, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L104-L141, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L156-L163, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L81-L99, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L109-L124, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L67-L78, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L136-L139, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L176-L177, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L165-L178, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L32-L44, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L116-L119, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L138-L139] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L32-L50, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L104-L141, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L156-L163, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L81-L99, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L109-L124, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L67-L78, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L136-L139, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L176-L177, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L165-L178, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L32-L44, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L116-L119, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L138-L139, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L165-L190, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L25-L29] feature: "xlsx-reader-structural-diff" entry_points: ["jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py"] source_globs: ["jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py"] @@ -52,3 +52,11 @@ Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xl Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L32–L44](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py#L32-L44), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L116–L119](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py#L116-L119), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L81–L99](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py#L81-L99), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L138–L139](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py#L138-L139) + + +**命令行入口与差分退出码契约** + +CLI 形式为 `python3 xlsx_reader.py FILE [--sheet NAME] [--preview N] [--diff-against OLD.xlsx] [--json]`:`--sheet` 接一个值(名称),`--preview` 是整数(默认 0);只有当 `--sheet` 与 `--preview` 同时为真值时才调用 preview(),因此默认 `--preview 0` 不触发预览。指定 `--diff-against OLD` 时对 `FILE`(新)与 OLD(旧)做结构差分,退出码为 `ok` 时 0、否则 1,JSON 分支仅输出报告。缺少 openpyxl 时启动即以退出码 2 终止。 + +Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L156–L163](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py#L156-L163), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L165–L190](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py#L165-L190), [jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py:L25–L29](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/xlsx/scripts/xlsx_reader.py#L25-L29) + diff --git a/knowledge/repos/jiuwenswarm/components/config-resources/knowledge-config-resources.md b/knowledge/repos/jiuwenswarm/components/config-resources/knowledge-config-resources.md index 0a53167f..9f0cee96 100644 --- a/knowledge/repos/jiuwenswarm/components/config-resources/knowledge-config-resources.md +++ b/knowledge/repos/jiuwenswarm/components/config-resources/knowledge-config-resources.md @@ -1,10 +1,10 @@ --- title: "内置日报技能:采集、报告接口与模型配置" created: 2026-10-01 -updated: 2026-10-01 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/collectors/aggregator.py:L65-L148, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/generators/report_generator.py:L45-L92, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/generators/report_generator.py:L63-L92, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/collectors/aggregator.py:L97-L148, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/generators/report_generator.py:L28-L39, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/analyzers/ai_analyzer.py:L104-L139, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/generators/report_generator.py:L77-L111, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/collectors/aggregator.py:L116-L148] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/collectors/aggregator.py:L65-L148, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/generators/report_generator.py:L45-L92, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/generators/report_generator.py:L63-L92, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/collectors/aggregator.py:L97-L148, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/generators/report_generator.py:L28-L39, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/analyzers/ai_analyzer.py:L104-L139, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/generators/report_generator.py:L77-L111, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/collectors/aggregator.py:L116-L148, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/baoyu-image-gen/scripts/providers/agnes.test.ts:L66-L120, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/baoyu-image-gen/scripts/providers/dashscope.test.ts:L343-L350, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/resources/agent/workspace/skills/agent-group-creator/scripts/register_group.py:L14-L30] --- # 内置日报技能:采集、报告接口与模型配置 @@ -51,3 +51,11 @@ ReportConfig 默认 enable_ai_analysis=False、include_trends=True、include_sug 来源:[jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/collectors/aggregator.py:L116–L148](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/advanced-daily-report/collectors/aggregator.py#L116-L148) + + +**baoyu-image-gen 供应商脚本的单元测试与技能脚本的运行时校验入口** + +baoyu-image-gen 的 provider 模块带有 node:test 单元测试(helper 单测类别,此处未执行):如 agnes.test.ts 用断言覆盖 snapDim 的 32 对齐、parseAspectRatio 的合法/非法输入、resolveSize 的 32 对齐与 2048 最大边,以及 validateArgs 对 --n>1 的拒绝;dashscope.test.ts 同样断言 n=2 被拒以防多图计费,并用 mock 的 globalThis.fetch 捕获请求体做契约断言。此外,agent-group-creator 的 register_group.py 提供 --validate-only 运行时校验入口:调用 load_agent_group_package 加载并校验包(含 README.md 存在、禁止符号链接检查),通过时输出 RESULT: PASS。 + +Sources / 来源:[jiuwenswarm/resources/agent/workspace/skills/baoyu-image-gen/scripts/providers/agnes.test.ts:L66–L120](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/baoyu-image-gen/scripts/providers/agnes.test.ts#L66-L120), [jiuwenswarm/resources/agent/workspace/skills/baoyu-image-gen/scripts/providers/dashscope.test.ts:L343–L350](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/baoyu-image-gen/scripts/providers/dashscope.test.ts#L343-L350), [jiuwenswarm/resources/agent/workspace/skills/agent-group-creator/scripts/register_group.py:L14–L30](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/resources/agent/workspace/skills/agent-group-creator/scripts/register_group.py#L14-L30) + diff --git a/knowledge/repos/jiuwenswarm/components/cron-scheduling/knowledge.md b/knowledge/repos/jiuwenswarm/components/cron-scheduling/knowledge.md index 77f793a8..283808a9 100644 --- a/knowledge/repos/jiuwenswarm/components/cron-scheduling/knowledge.md +++ b/knowledge/repos/jiuwenswarm/components/cron-scheduling/knowledge.md @@ -1,10 +1,10 @@ --- title: "cron-scheduling:CronJob 模型、双后端存储与投递路由" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/cron/store_base.py:L11-L70, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/cron/__init__.py:L1-L6, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/cron/factory.py:L54-L84, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/cron/store.py:L139-L170, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/cron/models.py:L80-L114, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/cron/cron_job_mutations.py:L26-L46, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/cron/models.py:L239-L264, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/cron/dingtalk_routing.py:L44-L66, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/cron/factory.py:L32-L51, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/cron/factory.py:L70-L84, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/cron/models.py:L175-L190, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/cron/models.py:L477-L540, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/cron/cron_expr.py:L55-L76, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/cron/cron_job_mutations.py:L120-L136, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/cron/cron_job_mutations.py:L221-L222] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/cron/store_base.py:L11-L70, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/cron/__init__.py:L1-L6, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/cron/factory.py:L54-L84, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/cron/store.py:L139-L170, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/cron/models.py:L80-L114, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/cron/cron_job_mutations.py:L26-L46, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/cron/models.py:L239-L264, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/cron/dingtalk_routing.py:L44-L66, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/cron/factory.py:L32-L51, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/cron/factory.py:L70-L84, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/cron/models.py:L175-L190, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/cron/models.py:L477-L540, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/cron/cron_expr.py:L55-L76, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/cron/cron_job_mutations.py:L120-L136, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/cron/cron_job_mutations.py:L221-L222, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/cron/store.py:L40-L40, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/runtime/cron/store.py:L326-L328] --- # cron-scheduling:CronJob 模型、双后端存储与投递路由 @@ -41,3 +41,11 @@ CronJob.from_dict 逐字段规整并校验(id/name/cron_expr/timezone/targets Sources / 来源:[jiuwenswarm/runtime/cron/models.py:L477–L540](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/runtime/cron/models.py#L477-L540), [jiuwenswarm/runtime/cron/cron_expr.py:L55–L76](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/runtime/cron/cron_expr.py#L55-L76), [jiuwenswarm/runtime/cron/cron_job_mutations.py:L120–L136](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/runtime/cron/cron_job_mutations.py#L120-L136), [jiuwenswarm/runtime/cron/cron_job_mutations.py:L221–L222](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/runtime/cron/cron_job_mutations.py#L221-L222) + + +**CronJobStoreBackend 后端协议** + +`jiuwenswarm/runtime/cron/store_base.py` 定义存储后端 Protocol `CronJobStoreBackend`:异步方法 `list_jobs`、`get_job(job_id)`、`create_job(...)`(全关键字参数,返回 `CronJob`)、`update_job(job_id, patch)`、`delete_job(job_id, *, force=False)`、`get_revision`、`watch(callback)` 与 `aclose`,并以 `supports_watch: bool` 声明后端是否支持远端变更监听;docstring 说明个人版用文件后端、HA appliance 选 etcd,`CronRunState` 不属于该协议(仅内存)。`FileCronJobStore` 与 `EtcdCronJobStore` 是该协议的两个实现,`watch` 在文件后端抛 `NotImplementedError`。 + +Sources / 来源:[jiuwenswarm/runtime/cron/store_base.py:L11–L70](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/runtime/cron/store_base.py#L11-L70), [jiuwenswarm/runtime/cron/store.py:L40–L40](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/runtime/cron/store.py#L40-L40), [jiuwenswarm/runtime/cron/store.py:L326–L328](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/runtime/cron/store.py#L326-L328) + diff --git a/knowledge/repos/jiuwenswarm/components/extensions-plugins/_index.md b/knowledge/repos/jiuwenswarm/components/extensions-plugins/_index.md index b23204be..483e7160 100644 --- a/knowledge/repos/jiuwenswarm/components/extensions-plugins/_index.md +++ b/knowledge/repos/jiuwenswarm/components/extensions-plugins/_index.md @@ -54,3 +54,11 @@ sources: [] - [YuanRong FaaS 函数调用(非流式 + SSE 流式)](feature-yuanrong-faas-invocation.md) - [jiuwenswarm 扩展与插件:video_duplex 实时音视频 RPC 与 AgentOS Router 客户端](knowledge.md) - [YuanRong Agent 容器文件传输(上传/下载/列举/建目录)](feature-yuanrong-agent-file-transfer.md) + +- [AgentOS 沙箱创建与幂等对账:实现深读](feature-depth-agentos-sandbox-create-lifecycle.md) + +- [Voice/Video Duplex Managed Agent Task Service (Durable Queue, Concurrency, Uncertainty Semantics):实现深读](feature-depth-video-agent-managed-task-service.md) + +- [YuanRong Agent 容器文件上传/下载/列举/建目录:实现深读](feature-depth-yuanrong-agent-file-transfer.md) + +- [YuanRong FaaS 函数调用(非流式 + SSE 流式):实现深读](feature-depth-yuanrong-faas-invocation.md) diff --git a/knowledge/repos/jiuwenswarm/components/extensions-plugins/feature-video-agent-managed-task-service.md b/knowledge/repos/jiuwenswarm/components/extensions-plugins/feature-video-agent-managed-task-service.md index 8d687980..db70480f 100644 --- a/knowledge/repos/jiuwenswarm/components/extensions-plugins/feature-video-agent-managed-task-service.md +++ b/knowledge/repos/jiuwenswarm/components/extensions-plugins/feature-video-agent-managed-task-service.md @@ -1,10 +1,10 @@ --- title: "Voice/Video Duplex Managed Agent Task Service(持久队列、并发与不确定性语义)" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/backend/tasks/service.py:L1-L16, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/backend/tasks/service.py:L34-L48, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/backend/tasks/service.py:L183-L236, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/backend/tasks/service.py:L276-L279, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/backend/tasks/service.py:L193-L210, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/backend/tasks/service.py:L211-L235, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/backend/tasks/service.py:L336-L374, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/backend/tasks/service.py:L413-L428, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/tests/backend/test_managed_tasks.py:L172-L194, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/tests/backend/test_managed_tasks.py:L127-L144, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/tests/backend/test_managed_tasks.py:L87-L106, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/tests/backend/test_managed_tasks.py:L241-L267] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/backend/tasks/service.py:L1-L16, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/backend/tasks/service.py:L34-L48, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/backend/tasks/service.py:L183-L236, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/backend/tasks/service.py:L276-L279, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/backend/tasks/service.py:L193-L210, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/backend/tasks/service.py:L211-L235, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/backend/tasks/service.py:L336-L374, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/backend/tasks/service.py:L413-L428, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/tests/backend/test_managed_tasks.py:L172-L194, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/tests/backend/test_managed_tasks.py:L127-L144, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/tests/backend/test_managed_tasks.py:L87-L106, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/tests/backend/test_managed_tasks.py:L241-L267, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/backend/tasks/service.py:L55-L77, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/backend/tasks/service.py:L86-L99] feature: "video-agent-managed-task-service" entry_points: ["jiuwenswarm/extensions/video_duplex/backend/tasks/service.py"] source_globs: ["jiuwenswarm/extensions/video_duplex/backend/tasks/service.py", "jiuwenswarm/extensions/video_duplex/backend/tasks/rail.py"] @@ -44,3 +44,13 @@ Sources / 来源:[jiuwenswarm/extensions/video_duplex/backend/tasks/service.py Sources / 来源:[jiuwenswarm/extensions/video_duplex/tests/backend/test_managed_tasks.py:L172–L194](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/video_duplex/tests/backend/test_managed_tasks.py#L172-L194), [jiuwenswarm/extensions/video_duplex/tests/backend/test_managed_tasks.py:L127–L144](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/video_duplex/tests/backend/test_managed_tasks.py#L127-L144), [jiuwenswarm/extensions/video_duplex/tests/backend/test_managed_tasks.py:L87–L106](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/video_duplex/tests/backend/test_managed_tasks.py#L87-L106), [jiuwenswarm/extensions/video_duplex/tests/backend/test_managed_tasks.py:L241–L267](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/video_duplex/tests/backend/test_managed_tasks.py#L241-L267) + + +**重启时以“不确定”替代自动重放** + +Inference / 设计推断(非作者历史意图): + +`start()` 接管独占租约后,把上一进程遗留的 `running/cancelling/waiting_user`(以及带 `resume_answer` 的排队任务)统一改写为 `unknown` 并记录错误 "Execution ownership lost; tools were not replayed",同时把 `claimed` 的变更降级为 `unknown`,而不是重新派发。推断其取舍:代价是这些任务无法自动完成、需要用户重新介入;收益是避免对已经可能产生过工具副作用的执行做二次重放(对应测试 test_restart_does_not_replay_dispatched_effect 断言重开的替换服务不再调用 executor)。与容量策略一致地,`unknown` 任务不占并发额度但保留资源/依赖约束,即用吞吐换取确定性安全。 + +Sources / 来源:[jiuwenswarm/extensions/video_duplex/backend/tasks/service.py:L55–L77](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/video_duplex/backend/tasks/service.py#L55-L77), [jiuwenswarm/extensions/video_duplex/backend/tasks/service.py:L86–L99](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/video_duplex/backend/tasks/service.py#L86-L99), [jiuwenswarm/extensions/video_duplex/tests/backend/test_managed_tasks.py:L172–L194](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/video_duplex/tests/backend/test_managed_tasks.py#L172-L194) + diff --git a/knowledge/repos/jiuwenswarm/components/extensions-plugins/feature-yuanrong-agent-file-transfer.md b/knowledge/repos/jiuwenswarm/components/extensions-plugins/feature-yuanrong-agent-file-transfer.md index 38ef5466..48a5d899 100644 --- a/knowledge/repos/jiuwenswarm/components/extensions-plugins/feature-yuanrong-agent-file-transfer.md +++ b/knowledge/repos/jiuwenswarm/components/extensions-plugins/feature-yuanrong-agent-file-transfer.md @@ -1,10 +1,10 @@ --- title: "YuanRong Agent 容器文件传输(上传/下载/列举/建目录)" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/yuanrong_frontend_client.py:L804-L812, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/container_file_http.py:L469-L479, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/container_file_http.py:L489-L549, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/container_file_http.py:L698-L743, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/yuanrong_frontend_client.py:L1027-L1041, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/yuanrong_frontend_client.py:L895-L903, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/container_file_http.py:L55-L67, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/container_file_http.py:L563-L565] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/yuanrong_frontend_client.py:L804-L812, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/container_file_http.py:L469-L479, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/container_file_http.py:L489-L549, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/container_file_http.py:L698-L743, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/yuanrong_frontend_client.py:L1027-L1041, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/yuanrong_frontend_client.py:L895-L903, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/container_file_http.py:L55-L67, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/container_file_http.py:L563-L565, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/yuanrong_frontend_client.py:L780-L812, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/yuanrong_frontend_client.py:L814-L922, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/yuanrong_frontend_client.py:L924-L967, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/container_file_http.py:L653-L674, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/container_file_http.py:L824-L870, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/yuanrong_frontend_client.py:L855-L867, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/extensions/test_yuanrong_frontend_client.py:L330-L366] feature: "yuanrong-agent-file-transfer" entry_points: ["jiuwenswarm/extensions/yuanrong_frontend_client.py"] source_globs: ["jiuwenswarm/extensions/yuanrong_frontend_client.py", "jiuwenswarm/gateway/channel_manager/web/container_file_http.py"] @@ -28,3 +28,27 @@ Sources / 来源:[jiuwenswarm/extensions/yuanrong_frontend_client.py:L804–L8 Sources / 来源:[jiuwenswarm/extensions/yuanrong_frontend_client.py:L1027–L1041](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/yuanrong_frontend_client.py#L1027-L1041), [jiuwenswarm/extensions/yuanrong_frontend_client.py:L895–L903](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/yuanrong_frontend_client.py#L895-L903), [jiuwenswarm/gateway/channel_manager/web/container_file_http.py:L55–L67](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/channel_manager/web/container_file_http.py#L55-L67), [jiuwenswarm/gateway/channel_manager/web/container_file_http.py:L563–L565](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/channel_manager/web/container_file_http.py#L563-L565) + + +**YuanrongFrontendAgentClient 的四个异步文件方法** + +`YuanrongFrontendAgentClient` 提供四个容器文件异步方法:`upload_agent_file(instance_id, path, data, *, auth_headers, trace_id)`(POST /api/agent/:id/files/upload)、`download_agent_file(instance_id, path, *, offset=0, limit=65536, ...)` 返回 `AgentFileDownloadChunk`、`list_agent_files(..., recursive=False, max_depth=0, ...)` 和 `mkdir_agent_dir(..., mode=None, recursive=False, ...)`。每个方法先 `_ensure_connected()`(未连接抛 RuntimeError),对空 instance_id/path 抛 `ValueError`,然后经 `bind_southbound_trace_id` 绑定 trace 并用 `asyncio.to_thread` 把同步 HTTP 调用移出事件循环。 + +Sources / 来源:[jiuwenswarm/extensions/yuanrong_frontend_client.py:L780–L812](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/yuanrong_frontend_client.py#L780-L812), [jiuwenswarm/extensions/yuanrong_frontend_client.py:L814–L922](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/yuanrong_frontend_client.py#L814-L922), [jiuwenswarm/extensions/yuanrong_frontend_client.py:L924–L967](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/yuanrong_frontend_client.py#L924-L967) + + + +**网关 /file-api 的流式下载与两条 download 分支** + +`/file-api/raw-file` 默认先取首个分块确定 Content-Type,再按 `_STREAM_CHUNK` 分块循环 `download_container_file` 并以 `StreamingResponse` 流式输出(带 `Cache-Control: no-store`);`/file-api/download` 则分两条路径:`kind` 为验证资产 token 时经 `fetch_agent_unary`(`ReqMethod.FILE_DOWNLOAD_VERIFIED_CHUNK`)向 AgentServer 取块并支持单区间 Range(206/416),否则从 token 解出 path/session 后走 `download_container_file` 分块流式下载。 + +Sources / 来源:[jiuwenswarm/gateway/channel_manager/web/container_file_http.py:L653–L674](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/channel_manager/web/container_file_http.py#L653-L674), [jiuwenswarm/gateway/channel_manager/web/container_file_http.py:L698–L743](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/channel_manager/web/container_file_http.py#L698-L743), [jiuwenswarm/gateway/channel_manager/web/container_file_http.py:L824–L870](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/channel_manager/web/container_file_http.py#L824-L870) + + + +**416 归一化为 EOF 空块与 trace_id 复用策略** + +下载在 HTTP 416(offset 已到/越过 EOF)时不向上抛 Range 错误,而是返回一个 `data=b""`、`eof=True` 的空 `AgentFileDownloadChunk`,使网关 /file-api 把它当作成功的空读取(代码注释明确此意图)。trace_id 方面,显式传入的 trace_id 会被保留复用(测试中 create/delete/get 三次调用使用同一 id),仅未显式提供时才每次铸造新 id。 + +Sources / 来源:[jiuwenswarm/extensions/yuanrong_frontend_client.py:L855–L867](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/yuanrong_frontend_client.py#L855-L867), [tests/unit_tests/extensions/test_yuanrong_frontend_client.py:L330–L366](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/extensions/test_yuanrong_frontend_client.py#L330-L366) + diff --git a/knowledge/repos/jiuwenswarm/components/extensions-plugins/feature-yuanrong-faas-invocation.md b/knowledge/repos/jiuwenswarm/components/extensions-plugins/feature-yuanrong-faas-invocation.md index a25514f0..a6d863d5 100644 --- a/knowledge/repos/jiuwenswarm/components/extensions-plugins/feature-yuanrong-faas-invocation.md +++ b/knowledge/repos/jiuwenswarm/components/extensions-plugins/feature-yuanrong-faas-invocation.md @@ -1,10 +1,10 @@ --- title: "YuanRong FaaS 函数调用(非流式 + SSE 流式)" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/yuanrong_frontend_client.py:L1549-L1562, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/yuanrong_frontend_client.py:L1945-L1975, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/clawee.py:L105-L117, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/clawee.py:L233-L276, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/agent_client/extension.py:L31-L57, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/yuanrong_frontend_client.py:L1748-L1787, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/yuanrong_frontend_client.py:L1553-L1562, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/yuanrong_frontend_client.py:L1579-L1612, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/yuanrong_frontend_client.py:L1650-L1695, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/clawee.py:L233-L299, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/clawee.py:L226-L240, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/clawee.py:L309-L316, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/yuanrong_frontend_client.py:L1862-L1876, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/yuanrong_frontend_client.py:L1963-L1975] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/yuanrong_frontend_client.py:L1549-L1562, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/yuanrong_frontend_client.py:L1945-L1975, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/clawee.py:L105-L117, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/clawee.py:L233-L276, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/agent_client/extension.py:L31-L57, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/yuanrong_frontend_client.py:L1748-L1787, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/yuanrong_frontend_client.py:L1553-L1562, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/yuanrong_frontend_client.py:L1579-L1612, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/yuanrong_frontend_client.py:L1650-L1695, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/clawee.py:L233-L299, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/clawee.py:L226-L240, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/clawee.py:L309-L316, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/yuanrong_frontend_client.py:L1862-L1876, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/yuanrong_frontend_client.py:L1963-L1975, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/yuanrong_frontend_client.py:L1806-L1846, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/yuanrong_frontend_client.py:L1848-L1914, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/yuanrong_frontend_client.py:L1732-L1787] feature: "yuanrong-faas-invocation" entry_points: ["jiuwenswarm/extensions/yuanrong_frontend_client.py"] source_globs: ["jiuwenswarm/extensions/yuanrong_frontend_client.py", "jiuwenswarm/extensions/clawee.py", "jiuwenswarm/extensions/agent_client/extension.py"] @@ -46,3 +46,11 @@ Inference / 设计推断(非作者历史意图): Sources / 来源:[jiuwenswarm/extensions/clawee.py:L226–L240](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/clawee.py#L226-L240), [jiuwenswarm/extensions/clawee.py:L309–L316](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/clawee.py#L309-L316), [jiuwenswarm/extensions/yuanrong_frontend_client.py:L1862–L1876](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/yuanrong_frontend_client.py#L1862-L1876), [jiuwenswarm/extensions/yuanrong_frontend_client.py:L1963–L1975](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/yuanrong_frontend_client.py#L1963-L1975) + + +**客户端调用入口:send_request 与 send_request_stream** + +`YuanrongFrontendAgentClient` 实现两条 FaaS 调用入口:`send_request(envelope)` 发送非流式请求,在内部线程执行 `_do_invoke`(`is_stream=False`),把 HTTP 响应体经 `_parse_invoke_response` 反解为 `AgentResponse`;调用抛出的 `YuanrongAgentApiError` 被捕获并转为 `ok=False`、`payload={"error": ...}` 的响应而非向上抛异常。`send_request_stream(envelope)` 是异步生成器:`is_stream=True` 且请求头带 `Accept: text/event-stream`,由后台线程 `_do_invoke_stream` 逐行解析 SSE `data: ` 前缀,经 `loop.call_soon_threadsafe` 写入 asyncio.Queue,事件循环侧逐块 yield `AgentResponseChunk`,收到 `[DONE]` 或 "done" 后补发一个 `is_complete=True` 的空 chunk 收尾。两条路径共用 `_invoke_headers`:`X-Instance-Session` 携带 sessionID/sessionTTL/concurrency,user_id 非空时附加 `X-Session-Context`,并统一应用 trace 头。 + +Sources / 来源:[jiuwenswarm/extensions/yuanrong_frontend_client.py:L1806–L1846](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/yuanrong_frontend_client.py#L1806-L1846), [jiuwenswarm/extensions/yuanrong_frontend_client.py:L1848–L1914](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/yuanrong_frontend_client.py#L1848-L1914), [jiuwenswarm/extensions/yuanrong_frontend_client.py:L1732–L1787](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/yuanrong_frontend_client.py#L1732-L1787) + diff --git a/knowledge/repos/jiuwenswarm/components/extensions-plugins/knowledge.md b/knowledge/repos/jiuwenswarm/components/extensions-plugins/knowledge.md index b94a7766..32c35478 100644 --- a/knowledge/repos/jiuwenswarm/components/extensions-plugins/knowledge.md +++ b/knowledge/repos/jiuwenswarm/components/extensions-plugins/knowledge.md @@ -1,10 +1,10 @@ --- title: "jiuwenswarm 扩展与插件:video_duplex 实时音视频 RPC 与 AgentOS Router 客户端" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:docs/zh/application-plugins.md:L57-L62, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:docs/zh/application-plugins.md:L145-L149, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/backend/video_live.py:L692-L698, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/backend/video_live.py:L170-L187, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/backend/video_live.py:L210-L250] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:docs/zh/application-plugins.md:L57-L62, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:docs/zh/application-plugins.md:L145-L149, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/backend/video_live.py:L692-L698, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/backend/video_live.py:L170-L187, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/backend/video_live.py:L210-L250, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/backend/video_live.py:L189-L208, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/backend/video_live.py:L71-L89, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/backend/video_live.py:L481-L488, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/backend/video_live.py:L646-L656, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/backend/video_live.py:L673-L691, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:docs/zh/application-plugins.md:L111-L133, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/backend/video_live.py:L265-L275, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/backend/video_live.py:L152-L159, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/backend/video_live.py:L374-L411, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/video_duplex/backend/video_live.py:L434-L448] --- # jiuwenswarm 扩展与插件:video_duplex 实时音视频 RPC 与 AgentOS Router 客户端 @@ -25,3 +25,27 @@ Sources / 来源:[docs/zh/application-plugins.md:L57–L62](https://github.com Sources / 来源:[jiuwenswarm/extensions/video_duplex/backend/video_live.py:L170–L187](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/video_duplex/backend/video_live.py#L170-L187), [jiuwenswarm/extensions/video_duplex/backend/video_live.py:L210–L250](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/video_duplex/backend/video_live.py#L210-L250) + + +**装配与日志职责** + +register_video_live_handler(channel) 是 video_duplex 后端的装配入口:构造 VideoSearchManager(注入延迟解析的 log_event/qwen_active 回调,使运行时或测试覆盖仍然生效)和 voice handlers,把全部处理器注册到 channel 后返回 search_manager。诊断日志由 _append_jsonl 统一实现:在 threading.Lock 下把单个 JSON 对象写成一行,覆盖 search 完成与 router 响应可能落在不同 worker 线程的并发追加;遥测、会话、ASR、JoyAI 等各写入 ~/.jiuwenswarm/logs 下不同的 jsonl 文件。注意并非所有客户端事件都进这些文件:不符合命名规则的遥测事件会被拒绝,会话事件走 append_history_record 持久化。 + +Sources / 来源:[jiuwenswarm/extensions/video_duplex/backend/video_live.py:L189–L208](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/video_duplex/backend/video_live.py#L189-L208), [jiuwenswarm/extensions/video_duplex/backend/video_live.py:L71–L89](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/video_duplex/backend/video_live.py#L71-L89), [jiuwenswarm/extensions/video_duplex/backend/video_live.py:L481–L488](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/video_duplex/backend/video_live.py#L481-L488), [jiuwenswarm/extensions/video_duplex/backend/video_live.py:L646–L656](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/video_duplex/backend/video_live.py#L646-L656) + + + +**RPC 注册契约与文档分歧** + +handlers 字典显式列出 video.realtime.config、video.joyai.frame、video.realtime.telemetry、video.conversation.append 以及五个 video.qwen.tool / video.search.* 方法,并合入 video_voice.create_voice_handlers 返回的额外处理器;每个方法都以 local_only=True、available_when_disabled=True 注册。这与上游文档存在分歧:docs/zh/application-plugins.md 规定 available_when_disabled 只应用于配置和启用状态等管理接口,不应赋给业务运行时接口,而此处的业务 RPC(如 video.joyai.frame)也带该标志——分歧按源码记录,不视为文档要求的豁免。参数校验示例:_joyai_frame 对非法图片 data URL 或超限 frame_data_url 返回 BAD_REQUEST 错误。 + +Sources / 来源:[jiuwenswarm/extensions/video_duplex/backend/video_live.py:L673–L691](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/video_duplex/backend/video_live.py#L673-L691), [docs/zh/application-plugins.md:L111–L133](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/docs/zh/application-plugins.md#L111-L133), [jiuwenswarm/extensions/video_duplex/backend/video_live.py:L265–L275](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/video_duplex/backend/video_live.py#L265-L275) + + + +**JoyAI delegation 的两条路径** + +JoyAI 结果的 decision 取值限定为 silence/response/delegation(_validate_joyai_result,非法结构抛 ValueError)。delegation 有两条路径:只有以 "{" 开头且能解析为仅含 name/arguments 的 JSON、name 属于 jiuwen_delegate/jiuwen_task_query/jiuwen_task_modify/jiuwen_task_cancel 之一时,才进入任务操作循环(最多 3 次,query/modify/cancel 的回执经 task_receipt_followup 送回同一 provider 会话);不以 "{" 开头的 delegation 直接跳出该循环,但其后只要 decision 仍为 delegation 且字符串非空,任何纯文本 delegation 也会作为 query 传给 search_manager.start 启动搜索任务。因此"delegation 只接受显式 JSON"不成立——JSON 校验只约束任务操作工具,不约束任务启动本身。 + +Sources / 来源:[jiuwenswarm/extensions/video_duplex/backend/video_live.py:L152–L159](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/video_duplex/backend/video_live.py#L152-L159), [jiuwenswarm/extensions/video_duplex/backend/video_live.py:L374–L411](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/video_duplex/backend/video_live.py#L374-L411), [jiuwenswarm/extensions/video_duplex/backend/video_live.py:L434–L448](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/video_duplex/backend/video_live.py#L434-L448) + diff --git a/knowledge/repos/jiuwenswarm/components/gateway-channels/_index.md b/knowledge/repos/jiuwenswarm/components/gateway-channels/_index.md index 46188ddd..ee708672 100644 --- a/knowledge/repos/jiuwenswarm/components/gateway-channels/_index.md +++ b/knowledge/repos/jiuwenswarm/components/gateway-channels/_index.md @@ -78,3 +78,21 @@ sources: [] - [3rdagent.list / 3rdagent.switch 第三方智能体切换](feature-thirdagent-list-switch.md) - [@path 文件引用内联与 @agent 提及解析(MessageHandler)](feature-at-file-reference-inlining-b1a822e1.md) - [scripts](scripts/_index.md) + +- [@path 文件引用内联与 @agent 提及解析:实现深读](feature-depth-at-file-reference-inlining-b1a822e1.md) + +- [/security-review 安全审查斜杠命令与 git 预执行:实现深读](feature-depth-channel-security-review-slash-command.md) + +- [Gateway Config-Save Hot Reload (agent.reload_config retry, restart fallback, browser/proactive side effects):实现深读](feature-depth-gateway-config-hot-reload.md) + +- [Gateway HealthCheck 周期探活服务:实现深读](feature-depth-gateway-health-check.md) + +- [GatewayServer 多路由 WebSocket 宿主与会话/请求路由表:实现深读](feature-depth-gateway-server-multi-route-ws.md) + +- [IM Attachment Persist Hook (E2A + HTTP Bridge):实现深读](feature-depth-im-attachment-persist-hook-969909e1.md) + +- [IM Channel Hot Reconfiguration (_apply_channel_config lifecycle across 11 channels):实现深读](feature-depth-im-channel-hot-reconfig.md) + +- [界面语言配置 RPC(preferred_language):实现深读](feature-depth-locale-conf-rpc.md) + +- [3rdagent.list / 3rdagent.switch 第三方智能体切换:实现深读](feature-depth-thirdagent-list-switch.md) diff --git a/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-at-file-reference-inlining-b1a822e1.md b/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-at-file-reference-inlining-b1a822e1.md index 2ebd03c4..3f31b1ef 100644 --- a/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-at-file-reference-inlining-b1a822e1.md +++ b/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-at-file-reference-inlining-b1a822e1.md @@ -1,10 +1,10 @@ --- title: "@path 文件引用内联与 @agent 提及解析(MessageHandler)" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/message_handler/message_handler.py:L2873-L2915, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/message_handler/message_handler.py:L2917-L2944, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/message_handler/message_handler.py:L2882-L2889, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/message_handler/message_handler.py:L2950-L2987, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/message_handler/message_handler.py:L3007-L3039, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/message_handler/message_handler.py:L2878-L2913, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/message_handler/message_handler.py:L2928-L2935, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/message_handler/message_handler.py:L2891-L2913, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/gateway/test_agent_mentions.py:L75-L77, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/message_handler/message_handler.py:L2917-L2924] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/message_handler/message_handler.py:L2873-L2915, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/message_handler/message_handler.py:L2917-L2944, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/message_handler/message_handler.py:L2882-L2889, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/message_handler/message_handler.py:L2950-L2987, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/message_handler/message_handler.py:L3007-L3039, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/message_handler/message_handler.py:L2878-L2913, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/message_handler/message_handler.py:L2928-L2935, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/message_handler/message_handler.py:L2891-L2913, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/gateway/test_agent_mentions.py:L75-L77, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/message_handler/message_handler.py:L2917-L2924, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/message_handler/message_handler.py:L2846-L2866, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/message_handler/message_handler.py:L2895-L2908] feature: "at-file-reference-inlining-b1a822e1" entry_points: ["jiuwenswarm/gateway/message_handler/message_handler.py"] source_globs: ["jiuwenswarm/gateway/message_handler/message_handler.py"] @@ -54,3 +54,11 @@ Sources / 来源:[jiuwenswarm/gateway/message_handler/message_handler.py:L2891 Sources / 来源:[tests/unit_tests/gateway/test_agent_mentions.py:L75–L77](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/gateway/test_agent_mentions.py#L75-L77), [jiuwenswarm/gateway/message_handler/message_handler.py:L2917–L2924](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/message_handler/message_handler.py#L2917-L2924) + + +**内联行为的可调参数与默认值** + +`resolve_at_file_references` 没有读取外部配置文件,其行为由两个调用参数控制:`cwd`(默认 `None`,回退 `os.getcwd()` 作为相对路径基准)与 `max_file_size`(默认取模块常量 `_DEFAULT_INLINE_FILE_SIZE_LIMIT`)。当 `max_file_size` 传 `None` 时跳过截断逻辑,直接 `read_text` 读入整个文件;有上限时按 `max_file_size + 1` 读取并在超限时截断,附 `... (truncated, original_size=N bytes)` 后缀。常量本身的具体数值与调用方是否覆盖默认值未在所示片段中出现。 + +Sources / 来源:[jiuwenswarm/gateway/message_handler/message_handler.py:L2846–L2866](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/message_handler/message_handler.py#L2846-L2866), [jiuwenswarm/gateway/message_handler/message_handler.py:L2895–L2908](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/message_handler/message_handler.py#L2895-L2908) + diff --git a/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-gateway-config-hot-reload.md b/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-gateway-config-hot-reload.md index 9eced16f..0a497b43 100644 --- a/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-gateway-config-hot-reload.md +++ b/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-gateway-config-hot-reload.md @@ -1,10 +1,10 @@ --- title: "Gateway Config-Save Hot Reload(_on_config_saved:agent.reload_config 重试、重启兜底与副作用)" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L2065-L2072, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L2113-L2124, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L2032-L2086, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L2119-L2125, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L2057-L2058, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L2090-L2135, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L2039-L2058, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L2137-L2159, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L2080-L2084, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L2102-L2125] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L2065-L2072, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L2113-L2124, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L2032-L2086, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L2119-L2125, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L2057-L2058, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L2090-L2135, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L2039-L2058, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L2137-L2159, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L2080-L2084, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L2102-L2125, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L2090-L2117, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L2065-L2077] feature: "gateway-config-hot-reload" entry_points: ["jiuwenswarm/gateway/app_gateway.py"] source_globs: ["jiuwenswarm/gateway/app_gateway.py"] @@ -52,3 +52,13 @@ Sources / 来源:[jiuwenswarm/gateway/app_gateway.py:L2039–L2058](https://gi Sources / 来源:[jiuwenswarm/gateway/app_gateway.py:L2080–L2084](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/app_gateway.py#L2080-L2084), [jiuwenswarm/gateway/app_gateway.py:L2102–L2125](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/app_gateway.py#L2102-L2125), [jiuwenswarm/gateway/app_gateway.py:L2137–L2159](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/app_gateway.py#L2137-L2159) + + +**重试退避与固定用户的取舍** + +Inference / 设计推断(非作者历史意图): + +重载采用最多 4 次尝试加指数退避(2、4、8 秒 sleep,不含每次请求本身的耗时),换取对瞬时失败的容忍;代价是被持续拒绝的保存需累计 14 秒退避后才会走 `_schedule_gateway_restart` 兜底并返回 False(推断:取舍分析基于所示控制流)。校验错误通过子串匹配("ValidationError"/"validation error"/"Field required")短路,避免对格式错误做无意义重试,但也意味着错误文案变化会使匹配失效。重载信封硬编码 user_id="agentos_test":代码注释记载这是为了让 faas 沙箱按 user_id 命中带完整工作区的 warm instance,避免空 user 的 60s invocation 超时与非配置用户的 80004 建沙箱失败;代价是重载依赖该部署默认用户存在(此历史动因来自 L2065–L2072 的维护者注释,非外部文档)。 + +Sources / 来源:[jiuwenswarm/gateway/app_gateway.py:L2057–L2058](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/app_gateway.py#L2057-L2058), [jiuwenswarm/gateway/app_gateway.py:L2090–L2117](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/app_gateway.py#L2090-L2117), [jiuwenswarm/gateway/app_gateway.py:L2119–L2125](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/app_gateway.py#L2119-L2125), [jiuwenswarm/gateway/app_gateway.py:L2065–L2077](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/app_gateway.py#L2065-L2077) + diff --git a/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-gateway-health-check.md b/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-gateway-health-check.md index 3ececf4e..8c98a7d8 100644 --- a/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-gateway-health-check.md +++ b/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-gateway-health-check.md @@ -1,10 +1,10 @@ --- title: "Gateway HealthCheck 周期探活服务 (jiuwenswarm/gateway/health_check)" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/health_check/health_check.py:L76-L92, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/health_check/health_check.py:L45-L62, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L3944-L3957, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/health_check/health_check.py:L124-L126, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/health_check/health_check.py:L266-L277, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/health_check/health_check.py:L3-L12, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/health_check/health_check.py:L192-L207, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/health_check/health_check.py:L242-L260, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/health_check/health_check.py:L3-L18, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/gateway/test_app_web_handlers.py:L379-L393] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/health_check/health_check.py:L76-L92, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/health_check/health_check.py:L45-L62, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L3944-L3957, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/health_check/health_check.py:L124-L126, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/health_check/health_check.py:L266-L277, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/health_check/health_check.py:L3-L12, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/health_check/health_check.py:L192-L207, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/health_check/health_check.py:L242-L260, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/health_check/health_check.py:L3-L18, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/gateway/test_app_web_handlers.py:L379-L393, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/health_check/__init__.py:L10-L28, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/health_check/health_check.py:L95-L115, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/health_check/health_check.py:L318-L340, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L3867-L3890, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/health_check/health_check.py:L166-L207, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/health_check/health_check.py:L305-L313] feature: "gateway-health-check" entry_points: ["jiuwenswarm/gateway/health_check/__init__.py", "jiuwenswarm/gateway/health_check/health_check.py"] source_globs: ["jiuwenswarm/gateway/health_check/__init__.py", "jiuwenswarm/gateway/health_check/health_check.py", "jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py"] @@ -44,3 +44,19 @@ Sources / 来源:[jiuwenswarm/gateway/health_check/health_check.py:L3–L12](h Sources / 来源:[jiuwenswarm/gateway/health_check/health_check.py:L3–L18](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/health_check/health_check.py#L3-L18), [jiuwenswarm/gateway/health_check/health_check.py:L242–L260](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/health_check/health_check.py#L242-L260), [jiuwenswarm/gateway/health_check/health_check.py:L266–L277](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/health_check/health_check.py#L266-L277), [jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L3944–L3957](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py#L3944-L3957), [tests/unit_tests/gateway/test_app_web_handlers.py:L379–L393](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/gateway/test_app_web_handlers.py#L379-L393) + + +**服务生命周期与 Web RPC 契约** + +模块通过 `jiuwenswarm.gateway.health_check` 包对外导出 `GatewayHealthCheckService`、`HealthCheckConfig`、`IHealthCheck` 等符号。`IHealthCheck` 抽象接口定义异步 `start()`/`stop()` 与 `is_running()` 三个生命周期方法;`GatewayHealthCheckService(agent_client, config, message_handler=None)` 是其实现,另暴露 `last_tick_ok`(True/False/None)与 `last_tick_at` 只读属性及 `get_health_check_conf()`/`set_health_check_conf(every=, target=, active_hours=)`。Web 侧注册 `health_check.get_conf`/`health_check.set_conf` RPC(`heartbeat.get_conf`/`set_conf` 是同一处理器的别名),服务不可用时返回 `SERVICE_UNAVAILABLE`,`every` 非法时抛 `ValueError` 映射为 `BAD_REQUEST`。 + +Sources / 来源:[jiuwenswarm/gateway/health_check/__init__.py:L10–L28](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/health_check/__init__.py#L10-L28), [jiuwenswarm/gateway/health_check/health_check.py:L95–L115](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/health_check/health_check.py#L95-L115), [jiuwenswarm/gateway/health_check/health_check.py:L318–L340](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/health_check/health_check.py#L318-L340), [jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L3867–L3890](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py#L3867-L3890) + + + +**支持的探活行为与依赖关系** + +GatewayHealthCheckService 提供固定间隔的 AgentServer 连通性探活:`_run_loop` 每轮先 `asyncio.sleep(interval_seconds)` 再执行一次 `_tick`,`_tick` 用 `e2a_from_agent_fields` 构造以 `HealthCheckConfig.channel_id`(默认 `__health_check__`,可配置)为标识、携带 `HEALTH_CHECK_PROMPT` 的 E2A 信封,经 `AgentServerClient.send_request` 发送,`timeout_seconds` > 0 时才包 `asyncio.wait_for`;该探活只验证请求链路,不读取或执行任何用户任务文件。成功后仅当配置了 `relay_channel_id` 且注入了 `message_handler` 时,才把响应内容以 `EventType.HEALTH_CHECK_RELAY` 的 event Message(payload 同时含 `health_check` 与已废弃的 `heartbeat` 别名字段)经 `publish_robot_messages` 回传到指定 channel;`active_hours` 支持跨午夜区间(start > end 时按 `now >= start or now < end` 判断)。 + +Sources / 来源:[jiuwenswarm/gateway/health_check/health_check.py:L166–L207](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/health_check/health_check.py#L166-L207), [jiuwenswarm/gateway/health_check/health_check.py:L242–L260](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/health_check/health_check.py#L242-L260), [jiuwenswarm/gateway/health_check/health_check.py:L305–L313](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/health_check/health_check.py#L305-L313) + diff --git a/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-gateway-server-multi-route-ws.md b/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-gateway-server-multi-route-ws.md index 3ca8ba14..92347ea9 100644 --- a/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-gateway-server-multi-route-ws.md +++ b/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-gateway-server-multi-route-ws.md @@ -1,10 +1,10 @@ --- title: "GatewayServer 多路由 WebSocket 宿主与会话/请求路由表" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L651-L680, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L1040-L1052, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L813-L847, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L1618-L1644, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L1060-L1066, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L1078-L1092, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L1094-L1105, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L1107-L1148, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L1572-L1592, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L943-L978, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L979-L1007] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L651-L680, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L1040-L1052, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L813-L847, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L1618-L1644, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L1060-L1066, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L1078-L1092, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L1094-L1105, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L1107-L1148, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L1572-L1592, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L943-L978, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L979-L1007, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L1540-L1555, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L1572-L1588, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L1693-L1745, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/gateway/test_app_gateway_acp.py:L572-L629, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/gateway/test_app_gateway_acp.py:L633-L668] feature: "gateway-server-multi-route-ws" entry_points: ["jiuwenswarm/gateway/app_gateway.py"] source_globs: ["jiuwenswarm/gateway/app_gateway.py", "jiuwenswarm/gateway/channel_manager/channel_manager.py", "jiuwenswarm/gateway/routing/route_binding.py", "jiuwenswarm/gateway/channel_manager/base.py", "jiuwenswarm/gateway/routing/keys.py"] @@ -46,3 +46,19 @@ Sources / 来源:[jiuwenswarm/gateway/app_gateway.py:L1060–L1066](https://gi Sources / 来源:[jiuwenswarm/gateway/app_gateway.py:L1572–L1592](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/app_gateway.py#L1572-L1592), [jiuwenswarm/gateway/app_gateway.py:L943–L978](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/app_gateway.py#L943-L978), [jiuwenswarm/gateway/app_gateway.py:L979–L1007](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/app_gateway.py#L979-L1007) + + +**_handle_raw_message 的分发管线与 forward 路径的提前拒绝** + +`_handle_raw_message` 按 JSON 解析 → ACP bridge → route.inbound_interceptor → req 帧校验的顺序预处理,随后进入方法分发。方法命中 forward_methods 并不必然转发:ReqMethod 枚举匹配失败时直接回 "unknown method" 错误帧(L1542–L1555),session_key 已绑定到另一个活跃连接时回 SESSION_IN_USE 错误帧并终止(L1572–L1588)。forward 分支正常派发后,非 ACP 路由上不在 forward_no_local_handler_methods 中的方法会继续落入 local_handlers 查找,仍无匹配才回 unknown method(L1699–L1745)。 + +Sources / 来源:[jiuwenswarm/gateway/app_gateway.py:L1540–L1555](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/app_gateway.py#L1540-L1555), [jiuwenswarm/gateway/app_gateway.py:L1572–L1588](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/app_gateway.py#L1572-L1588), [jiuwenswarm/gateway/app_gateway.py:L1693–L1745](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/app_gateway.py#L1693-L1745) + + + +**路由绑定与 stale 清理提升的运行时单元测试** + +tests/unit_tests/gateway/test_app_gateway_acp.py 含针对 GatewayServer 的运行时单元测试(测试存在但未在本次输入中执行)。test_gateway_server_binds_session_for_local_request_and_calls_hook 通过探针方法 handle_raw_message_public 喂入 /tui 路由的 config.get 请求,断言 session_bind_handler 以 ("tui", "sess-local") 被调用且后续 event 帧能路由回同一 ws;test_gateway_server_promotes_pending_session_client_after_stale_owner_cleanup 验证绑定冲突返回 False 后,旧连接经 _connection_handler 清理时触发 disconnect_handler 并把 pending 新 ws 提升进 _session_to_client。 + +Sources / 来源:[tests/unit_tests/gateway/test_app_gateway_acp.py:L572–L629](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/gateway/test_app_gateway_acp.py#L572-L629), [tests/unit_tests/gateway/test_app_gateway_acp.py:L633–L668](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/gateway/test_app_gateway_acp.py#L633-L668) + diff --git a/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-im-attachment-persist-hook-969909e1.md b/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-im-attachment-persist-hook-969909e1.md index 262b811d..b23a3f9c 100644 --- a/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-im-attachment-persist-hook-969909e1.md +++ b/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-im-attachment-persist-hook-969909e1.md @@ -1,10 +1,10 @@ --- title: "IM Attachment Persist Hook (E2A + HTTP Bridge) — ChannelManager wiring" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/channel_manager.py:L163-L183, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/channel_manager.py:L230-L244, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/channel_manager.py:L206-L229, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/channel_manager.py:L260-L262, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/channel_manager.py:L127-L162, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/channel_manager.py:L176-L185, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/channel_manager.py:L223-L229, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/channel_manager.py:L186-L193, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/channel_manager.py:L195-L219, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/channel_manager.py:L127-L147, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/channel_manager.py:L163-L185, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/channel_manager.py:L195-L229, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/channel_manager.py:L266-L272] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/channel_manager.py:L163-L183, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/channel_manager.py:L230-L244, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/channel_manager.py:L206-L229, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/channel_manager.py:L260-L262, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/channel_manager.py:L127-L162, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/channel_manager.py:L176-L185, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/channel_manager.py:L223-L229, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/channel_manager.py:L186-L193, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/channel_manager.py:L195-L219, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/channel_manager.py:L127-L147, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/channel_manager.py:L163-L185, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/channel_manager.py:L195-L229, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/channel_manager.py:L266-L272, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/channel/test_attachment_persist.py:L160-L182, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/channel/test_attachment_persist.py:L203-L234] feature: "im-attachment-persist-hook-969909e1" entry_points: ["jiuwenswarm/gateway/channel_manager/channel_manager.py"] source_globs: ["jiuwenswarm/gateway/channel_manager/channel_manager.py"] @@ -52,3 +52,11 @@ ChannelManager wires the attachment persist hook at two registration points: `re Sources / 来源:[jiuwenswarm/gateway/channel_manager/channel_manager.py:L127–L147](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/channel_manager/channel_manager.py#L127-L147), [jiuwenswarm/gateway/channel_manager/channel_manager.py:L163–L185](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/channel_manager/channel_manager.py#L163-L185), [jiuwenswarm/gateway/channel_manager/channel_manager.py:L195–L229](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/channel_manager/channel_manager.py#L195-L229), [jiuwenswarm/gateway/channel_manager/channel_manager.py:L266–L272](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/channel_manager/channel_manager.py#L266-L272) + + +**Attachment persist hook unit tests** + +Runtime pytest unit tests exist for the hook's routing-mode behavior. `test_agentos_attachment_never_falls_back_to_gateway_workspace` (pytest.mark.asyncio) wires the hook via `manager._try_wire_file_persist_hook` with `is_agentos_routing_client` monkeypatched to True, then asserts invoking `channel.hook(b"x", "images", "a.png")` raises RuntimeError matching "authenticated AgentOS user_id", matching the source's failing-hook branch. `test_legacy_single_user_keeps_file_service_local_persistence` monkeypatches `is_legacy_shared_directory_client` to True and asserts no hook is installed (`channel.hook is None`). `test_enterprise_feishu_bot_uses_safe_attachment_storage_platform` monkeypatches `e2a_proxy.fetch_agent_unary`, sets `channel_id = "feishu_enterprise:bot-a"`, and asserts the E2A params carry the sanitized `platform == "feishu_enterprise_bot-a"`. Tests have not been executed here. + +Sources / 来源:[tests/unit_tests/channel/test_attachment_persist.py:L160–L182](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/channel/test_attachment_persist.py#L160-L182), [tests/unit_tests/channel/test_attachment_persist.py:L203–L234](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/channel/test_attachment_persist.py#L203-L234), [jiuwenswarm/gateway/channel_manager/channel_manager.py:L163–L185](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/channel_manager/channel_manager.py#L163-L185) + diff --git a/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-im-channel-hot-reconfig.md b/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-im-channel-hot-reconfig.md index ffc01162..c2ffe70b 100644 --- a/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-im-channel-hot-reconfig.md +++ b/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-im-channel-hot-reconfig.md @@ -1,10 +1,10 @@ --- title: "IM Channel Hot Reconfiguration (_apply_channel_config lifecycle across 11 channels)" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L2466-L2517, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L2576-L2643, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L2552-L2564, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L2591-L2643, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L2669-L2721, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L4023-L4046, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L4277-L4288, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L4490-L4503] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L2466-L2517, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L2576-L2643, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L2552-L2564, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L2591-L2643, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L2669-L2721, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L4023-L4046, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L4277-L4288, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L4490-L4503, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L2528-L2538, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L3112-L3112, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L2519-L2526, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L3001-L3024, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/app_gateway.py:L2922-L2926] feature: "im-channel-hot-reconfig" entry_points: ["jiuwenswarm/gateway/app_gateway.py"] source_globs: ["jiuwenswarm/gateway/app_gateway.py", "jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py"] @@ -36,3 +36,19 @@ Web 处理器在写配置前做输入校验:非 dict 的 params 返回 `BAD_RE Sources / 来源:[jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L4023–L4046](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py#L4023-L4046), [jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L4277–L4288](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py#L4277-L4288), [jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L4490–L4503](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py#L4490-L4503) + + +**_apply_channel_config 回调契约** + +`_apply_channel_config(conf: dict)` 由 `_run` 协程定义并通过 `channel_manager.set_config_callback` 注册(app_gateway.py:3112),频道实例与 `_last_channels_conf` 等状态是 `_run` 的局部变量,经 nonlocal 声明修改(L2528-L2538),不是模块级状态。停止路径 `_stop_channel(channel, task, channel_name, background_wait=False)` 默认同步 `await asyncio.wait_for(task, timeout=5.0)` 等待取消、`channel.stop()` 以 10 秒超时(L2495, L2512);`background_wait=True` 时改为 `asyncio.create_task(wait_cancel())` 后台等待,取消无需在 stop/unregister 之前完成(L2478-L2492, L2510-L2517)。 + +Sources / 来源:[jiuwenswarm/gateway/app_gateway.py:L2466–L2517](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/app_gateway.py#L2466-L2517), [jiuwenswarm/gateway/app_gateway.py:L2528–L2538](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/app_gateway.py#L2528-L2538), [jiuwenswarm/gateway/app_gateway.py:L3112–L3112](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/app_gateway.py#L3112-L3112) + + + +**频道启用判定与 Wechat 默认值** + +`_is_channel_enabled(conf, required_fields)` 在 `enabled` 键存在时以其布尔值为准;键值为 None(如显式 enabled: null)时退化为检查必填字段是否全部非空(app_gateway.py:2519-2526)。WeChat 块使用空的 required_fields 列表并填充默认值,如 `base_url` 默认 `https://ilinkai.weixin.qq.com`、`auto_login` 默认 True、`qrcode_poll_interval_sec` 2.0、`long_poll_timeout_sec` 45、backoff 1.0–30.0 秒、credential_file 默认 `~/.wx-ai-bridge/credentials.json`(L3008-3024)。注意 WhatsApp 不走 `_is_channel_enabled`,在 L2922-2926 内联判定(enabled 缺省时以 bridge_ws_url 非空为准)。 + +Sources / 来源:[jiuwenswarm/gateway/app_gateway.py:L2519–L2526](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/app_gateway.py#L2519-L2526), [jiuwenswarm/gateway/app_gateway.py:L3001–L3024](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/app_gateway.py#L3001-L3024), [jiuwenswarm/gateway/app_gateway.py:L2922–L2926](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/app_gateway.py#L2922-L2926) + diff --git a/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-thirdagent-list-switch.md b/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-thirdagent-list-switch.md index 6c88633c..443f7db1 100644 --- a/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-thirdagent-list-switch.md +++ b/knowledge/repos/jiuwenswarm/components/gateway-channels/feature-thirdagent-list-switch.md @@ -1,10 +1,10 @@ --- title: "3rdagent.list / 3rdagent.switch 第三方智能体切换" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/agentos/agentos_router/router_client.py:L1893-L1909, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/agentos/agentos_router/router_client.py:L1947-L1975, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/routing/third_agent.py:L3-L7, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/agentos/agentos_router/router_client.py:L1878-L1896, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/common/client/third_agent.py:L63-L82, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/agentos/agentos_router/router_client.py:L1910-L1921, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/common/client/third_agent.py:L24-L49, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/common/client/third_agent.py:L52-L82, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/agentos/agentos_router/router_client.py:L2013-L2021, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/agentos/agentos_router/router_client.py:L1844-L1864, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/agentos/agentos_router/router_client.py:L2019-L2036, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/agentos/agentos_router/router_client.py:L1790-L1796, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/common/client/third_agent.py:L3-L15, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/routing/third_agent.py:L3-L17, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/agentos/agentos_router/router_client.py:L1817-L1842, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/agentos/agentos_router/router_client.py:L1910-L1929] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/agentos/agentos_router/router_client.py:L1893-L1909, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/agentos/agentos_router/router_client.py:L1947-L1975, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/routing/third_agent.py:L3-L7, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/agentos/agentos_router/router_client.py:L1878-L1896, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/common/client/third_agent.py:L63-L82, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/agentos/agentos_router/router_client.py:L1910-L1921, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/common/client/third_agent.py:L24-L49, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/common/client/third_agent.py:L52-L82, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/agentos/agentos_router/router_client.py:L2013-L2021, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/agentos/agentos_router/router_client.py:L1844-L1864, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/agentos/agentos_router/router_client.py:L2019-L2036, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/agentos/agentos_router/router_client.py:L1790-L1796, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/common/client/third_agent.py:L3-L15, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/routing/third_agent.py:L3-L17, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/agentos/agentos_router/router_client.py:L1817-L1842, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/agentos/agentos_router/router_client.py:L1910-L1929, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/agentos/agentos_router/router_client.py:L1866-L1921, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/agentos/agentos_router/router_client.py:L1602-L1608, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/extensions/agentos/agentos_router/router_client.py:L2007-L2021] feature: "thirdagent-list-switch" entry_points: ["jiuwenswarm/extensions/agentos/agentos_router/router_client.py"] source_globs: ["jiuwenswarm/extensions/agentos/agentos_router/router_client.py", "jiuwenswarm/common/client/third_agent.py", "jiuwenswarm/gateway/routing/third_agent.py"] @@ -54,3 +54,11 @@ Sources / 来源:[jiuwenswarm/extensions/agentos/agentos_router/router_client. Sources / 来源:[jiuwenswarm/common/client/third_agent.py:L3–L15](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/common/client/third_agent.py#L3-L15), [jiuwenswarm/gateway/routing/third_agent.py:L3–L17](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/routing/third_agent.py#L3-L17), [jiuwenswarm/extensions/agentos/agentos_router/router_client.py:L1817–L1842](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/agentos/agentos_router/router_client.py#L1817-L1842), [jiuwenswarm/extensions/agentos/agentos_router/router_client.py:L1910–L1929](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/agentos/agentos_router/router_client.py#L1910-L1929) + + +**支持的切换行为与依赖** + +`thirdagent_switch` 确保 (user_id, agent_type) 的 runtime 存在但不转发聊天:builtin `jiuwenswarm` 类型走捷径,仅更新 `_current_agent_types[uid]` 并返回空 agent_id/sandbox_id 的 READY payload,不创建沙箱;第三方类型经 `AgentManager.get_or_create_agent` 复用/创建实例。若配置了 SSH relay,switch 在返回前先等 YuanRong status=running 再探测南向 SSH。配套行为:E2A chat 请求路由到非 builtin 的 agent_type 时被拒绝,错误信息指明该类型不走 websocket、应改用 `3rdagent.switch` / SSH 接入。无扩展注册时 `UnsupportedThirdAgent` 对 list/switch 均返回 `UNSUPPORTED`。注意 `ssh_private_key` 字段仅在配置了密钥签发器且签发成功时出现,未注入签发器时成功 payload 不含该字段。 + +Sources / 来源:[jiuwenswarm/extensions/agentos/agentos_router/router_client.py:L1866–L1921](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/agentos/agentos_router/router_client.py#L1866-L1921), [jiuwenswarm/extensions/agentos/agentos_router/router_client.py:L1602–L1608](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/agentos/agentos_router/router_client.py#L1602-L1608), [jiuwenswarm/extensions/agentos/agentos_router/router_client.py:L2007–L2021](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/extensions/agentos/agentos_router/router_client.py#L2007-L2021), [jiuwenswarm/common/client/third_agent.py:L52–L82](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/common/client/third_agent.py#L52-L82) + diff --git a/knowledge/repos/jiuwenswarm/components/gateway-channels/knowledge-gateway-channels.md b/knowledge/repos/jiuwenswarm/components/gateway-channels/knowledge-gateway-channels.md index 385fb854..445e2897 100644 --- a/knowledge/repos/jiuwenswarm/components/gateway-channels/knowledge-gateway-channels.md +++ b/knowledge/repos/jiuwenswarm/components/gateway-channels/knowledge-gateway-channels.md @@ -1,10 +1,10 @@ --- title: "Gateway Web 频道处理器(channel_manager/web/app_web_handlers.py)" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:.doc_project_maintainer/project/flows/gateway-agentserver-e2a-chat.md:L57-L63, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:.doc_project_maintainer/modules/gateway-and-channels/README.md:L36-L40, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L1915-L1932, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L2035-L2052, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L390-L399, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L2054-L2094, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L2104-L2128, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L2130-L2169, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L755-L792, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L1399-L1404, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L1425-L1428, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L1499-L1502] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:.doc_project_maintainer/project/flows/gateway-agentserver-e2a-chat.md:L57-L63, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:.doc_project_maintainer/modules/gateway-and-channels/README.md:L36-L40, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L1915-L1932, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L2035-L2052, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L390-L399, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L2054-L2094, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L2104-L2128, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L2130-L2169, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L755-L792, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L1399-L1404, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L1425-L1428, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L1499-L1502, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L1679-L1692, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L1822-L1838, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L1755-L1762, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L1803-L1812, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L402-L410, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L752-L793] --- # Gateway Web 频道处理器(channel_manager/web/app_web_handlers.py) @@ -43,3 +43,19 @@ Sources / 来源:[jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py: Sources / 来源:[jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L755–L792](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py#L755-L792), [jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L1399–L1404](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py#L1399-L1404), [jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L1425–L1428](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py#L1425-L1428), [jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L1499–L1502](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py#L1499-L1502) + + +**大附件的传输取舍:预算内走 E2A,超预算按客户端类型分流** + +转发 media.persist / document.persist 前,Gateway 用 `E2A_PAYLOAD_MAX_BYTES` 减去其余字段的开销算出预算:预算内的 base64 项原样随 E2A 转发;超预算项被解码后上传。上传路径按 AgentServer 客户端类型分流——AgentOS 路由客户端走 `upload_file_bytes_via_e2a` HTTP bridge,而旧式单用户模式(AgentServer 无 HTTP 上传监听)直接写入共享用户目录 `_persist_media_locally`,落盘路径与 AgentServer 侧 `_store_image_item`/`_store_document_item` 一致,避免注定失败的 HTTP 尝试。上传失败时保留原 base64 项,只有当它仍超帧限制时才由下游链路返回可重试错误(L1759、L1906 的注释均为条件表述)。 + +Sources / 来源:[jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L1679–L1692](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py#L1679-L1692), [jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L1822–L1838](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py#L1822-L1838), [jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L1755–L1762](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py#L1755-L1762), [jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L1803–L1812](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py#L1803-L1812) + + + +**Web 频道转发方法集与微信参数写盘前校验** + +该模块定义 `_FORWARD_REQ_METHODS`,把 Web 前端的 RPC method(如 initialize、chat.send、chat.interrupt、session.fork、skills.*、agents.*、schedule.*、proactive.feedback 等)直接转发给 Agent 的 Web method 处理。另一个已实现功能是微信通道数值参数的写盘前校验:`_validate_wechat_numeric_params` 对 `channel.wechat.set_conf` 中的 `qrcode_poll_interval_sec`、`long_poll_timeout_sec`(须为整数)、`backoff_base_sec`、`backoff_max_sec` 检查有限正数与取值范围(0.1–3600 / 1–600),拒绝 bool 冒充数字;`backoff_max_sec` 不得小于 `backoff_base_sec` 的跨字段约束仅在两个字段同时出现在 params 中时才校验,缺省字段交由默认值处理。校验返回 None 表示合法,非法返回中文错误描述。 + +Sources / 来源:[jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L402–L410](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py#L402-L410), [jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py:L752–L793](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/gateway/channel_manager/web/app_web_handlers.py#L752-L793) + diff --git a/knowledge/repos/jiuwenswarm/components/gateway-channels/knowledge.md b/knowledge/repos/jiuwenswarm/components/gateway-channels/knowledge.md index 9d23a866..6cd92254 100644 --- a/knowledge/repos/jiuwenswarm/components/gateway-channels/knowledge.md +++ b/knowledge/repos/jiuwenswarm/components/gateway-channels/knowledge.md @@ -1,10 +1,10 @@ --- title: "进程式 CLI 频道(process_cli):REPL、worker 与会话操作" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:.doc_project_maintainer/project/flows/runtime-session-reference-chain.md:L66-L70, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:.doc_project_maintainer/modules/runtime-session/README.md:L42-L45, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/process_cli/repl.py:L371-L379, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/process_cli/repl.py:L407-L414, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/process_cli/repl.py:L484-L487, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/process_cli/commands.py:L75-L116, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/process_cli/repl.py:L228-L275, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/process_cli/repl.py:L297-L330, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/process_cli/repl.py:L738-L763, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/process_cli/live_layout.py:L23-L61] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:.doc_project_maintainer/project/flows/runtime-session-reference-chain.md:L66-L70, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:.doc_project_maintainer/modules/runtime-session/README.md:L42-L45, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/process_cli/repl.py:L371-L379, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/process_cli/repl.py:L407-L414, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/process_cli/repl.py:L484-L487, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/process_cli/commands.py:L75-L116, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/process_cli/repl.py:L228-L275, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/process_cli/repl.py:L297-L330, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/process_cli/repl.py:L738-L763, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/process_cli/live_layout.py:L23-L61, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/process_cli/repl.py:L61-L66, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/process_cli/repl.py:L81-L87, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/process_cli/commands.py:L42-L57] --- # 进程式 CLI 频道(process_cli):REPL、worker 与会话操作 @@ -33,3 +33,11 @@ REPL 支持会话 create/switch(/resume、别名 /continue)/fork(/branch Sources / 来源:[jiuwenswarm/channels/process_cli/repl.py:L228–L275](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/process_cli/repl.py#L228-L275), [jiuwenswarm/channels/process_cli/repl.py:L297–L330](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/process_cli/repl.py#L297-L330), [jiuwenswarm/channels/process_cli/repl.py:L738–L763](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/process_cli/repl.py#L738-L763), [jiuwenswarm/channels/process_cli/live_layout.py:L23–L61](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/process_cli/live_layout.py#L23-L61) + + +**Fixed worker environment, mode-target table, and interrupt grace constants** + +Configuration here is implemented constants and internal branch defaults rather than external settings. `_worker_environment()` copies the parent environment and forces `PYTHONIOENCODING=utf-8` and `PYTHONUTF8=1` so the parent/worker stdio pipes share one explicit wire encoding. Interrupt handling uses fixed escalation timeouts: `_INTERRUPT_GRACE_SECONDS = 15.0` after SIGINT (CTRL_BREAK_EVENT on Windows, where the worker is launched with CREATE_NEW_PROCESS_GROUP), then `_TERMINATE_GRACE_SECONDS = 5.0`, then `_KILL_GRACE_SECONDS = 5.0`. Mode selection is governed by the `_MODE_TARGETS` table in commands.py, which normalizes aliases like `agent`, `code.team`, or `team.normal` to canonical `*.normal` Runtime modes (e.g. `team` → `team.work.normal`). + +Sources / 来源:[jiuwenswarm/channels/process_cli/repl.py:L61–L66](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/process_cli/repl.py#L61-L66), [jiuwenswarm/channels/process_cli/repl.py:L81–L87](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/process_cli/repl.py#L81-L87), [jiuwenswarm/channels/process_cli/repl.py:L297–L330](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/process_cli/repl.py#L297-L330), [jiuwenswarm/channels/process_cli/commands.py:L42–L57](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/process_cli/commands.py#L42-L57) + diff --git a/knowledge/repos/jiuwenswarm/components/ide-clients/_index.md b/knowledge/repos/jiuwenswarm/components/ide-clients/_index.md index 4fb8e5b2..e3a3a4ae 100644 --- a/knowledge/repos/jiuwenswarm/components/ide-clients/_index.md +++ b/knowledge/repos/jiuwenswarm/components/ide-clients/_index.md @@ -32,3 +32,7 @@ sources: [] - [IDE 端代理文件编辑直接应用(DiffApplier)](feature-ide-file-edit-diff-apply.md) - [IDE 单轮文件快照与回退(Rewind)](feature-ide-turn-rewind-snapshot.md) - [shared-webview](shared-webview/_index.md) + +- [IDE 端代理文件编辑直接应用(DiffApplier):实现深读](feature-depth-ide-file-edit-diff-apply.md) + +- [IDE 单轮文件快照与回退(Rewind):实现深读](feature-depth-ide-turn-rewind-snapshot.md) diff --git a/knowledge/repos/jiuwenswarm/components/ide-clients/feature-ide-file-edit-diff-apply.md b/knowledge/repos/jiuwenswarm/components/ide-clients/feature-ide-file-edit-diff-apply.md index 76b2a980..9ab6f8b2 100644 --- a/knowledge/repos/jiuwenswarm/components/ide-clients/feature-ide-file-edit-diff-apply.md +++ b/knowledge/repos/jiuwenswarm/components/ide-clients/feature-ide-file-edit-diff-apply.md @@ -1,10 +1,10 @@ --- title: "IDE 端代理文件编辑直接应用(DiffApplier)" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L70-L84, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L27-L48, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/editor/DiffApplier.kt:L44-L56, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L85-L123, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L148-L164, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L273-L286, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L288-L294, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/ui/ChatPanel.ts:L368-L396, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L5-L16, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/ui/ChatPanel.ts:L355-L404, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/ui/ChatPanel.ts:L464-L471, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L81-L84, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/ui/ChatPanel.ts:L368-L404, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/editor/DiffApplier.kt:L70-L78] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L70-L84, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L27-L48, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/editor/DiffApplier.kt:L44-L56, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L85-L123, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L148-L164, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L273-L286, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L288-L294, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/ui/ChatPanel.ts:L368-L396, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L5-L16, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/ui/ChatPanel.ts:L355-L404, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/ui/ChatPanel.ts:L464-L471, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L81-L84, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/ui/ChatPanel.ts:L368-L404, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/editor/DiffApplier.kt:L70-L78, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L50-L64, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L129-L146, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/ui/ChatPanel.ts:L387-L404] feature: "ide-file-edit-diff-apply" entry_points: ["jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/ui/ChatToolWindow.kt", "jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts"] source_globs: ["jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/ui/ChatToolWindow.kt", "jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts", "jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/editor/DiffApplier.kt", "jiuwenswarm/channels/ide/packages/vscode-extension/src/ui/ChatPanel.ts"] @@ -52,3 +52,13 @@ VS Code 端通过 `vscode.workspace.getConfiguration('jiuwenswarm')` 读取三 Sources / 来源:[jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L81–L84](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts#L81-L84), [jiuwenswarm/channels/ide/packages/vscode-extension/src/ui/ChatPanel.ts:L368–L404](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/vscode-extension/src/ui/ChatPanel.ts#L368-L404), [jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/editor/DiffApplier.kt:L70–L78](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/editor/DiffApplier.kt#L70-L78) + + +**设计取舍:默认直接应用、整文件重写与快照补偿** + +Inference / 设计推断(非作者历史意图): + +VS Code 端 `approveEdits` 默认为 false,即代理编辑默认不经确认直接写入工作区;作为补偿,模块在每回合首次编辑前用 `ensureSnapshot` 在内存中保存文件原文(不存在记为 null),`chat.final` 时提升为 lastTurn 快照供 rewind 删除新建文件或还原内容。另一取舍是所有编辑(包括单处 str_replace)都通过 `replaceWholeFile` 以整文件范围 WorkspaceEdit 重写并保存,而非最小化补丁——实现简单且天然覆盖新建文件路径,但找不到 old_str 时(indexOf < 0)整个编辑失败并仅弹通知。此外 ChatPanel 在 `useDiffViewer` 开启但无法计算提议内容时会回退为直接应用,即审查路径本身可被绕过。以上动机性分析为推断,所示输入无文档佐证。 + +Sources / 来源:[jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L81–L84](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts#L81-L84), [jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L50–L64](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts#L50-L64), [jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L129–L146](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts#L129-L146), [jiuwenswarm/channels/ide/packages/vscode-extension/src/ui/ChatPanel.ts:L387–L404](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/vscode-extension/src/ui/ChatPanel.ts#L387-L404) + diff --git a/knowledge/repos/jiuwenswarm/components/ide-clients/feature-ide-turn-rewind-snapshot.md b/knowledge/repos/jiuwenswarm/components/ide-clients/feature-ide-turn-rewind-snapshot.md index 61410961..712521f0 100644 --- a/knowledge/repos/jiuwenswarm/components/ide-clients/feature-ide-turn-rewind-snapshot.md +++ b/knowledge/repos/jiuwenswarm/components/ide-clients/feature-ide-turn-rewind-snapshot.md @@ -1,10 +1,10 @@ --- title: "IDE 单轮文件快照与回退(Rewind)" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/ui/ChatToolWindow.kt:L627-L630, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/settings/JiuwenSwarmSettings.kt:L30-L34, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/ui/ChatToolWindow.kt:L503-L512, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/ui/ChatToolWindow.kt:L641-L649, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/ui/ChatToolWindow.kt:L622-L650, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/ui/ChatToolWindow.kt:L494-L502, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/ui/ChatToolWindow.kt:L315-L318, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/ui/ChatToolWindow.kt:L113-L117, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/ui/ChatToolWindow.kt:L486-L512, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L26-L64] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/ui/ChatToolWindow.kt:L627-L630, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/settings/JiuwenSwarmSettings.kt:L30-L34, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/ui/ChatToolWindow.kt:L503-L512, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/ui/ChatToolWindow.kt:L641-L649, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/ui/ChatToolWindow.kt:L622-L650, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/ui/ChatToolWindow.kt:L494-L502, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/ui/ChatToolWindow.kt:L315-L318, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/ui/ChatToolWindow.kt:L113-L117, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/ui/ChatToolWindow.kt:L486-L512, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L26-L64, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/ui/ChatToolWindow.kt:L627-L649, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L32-L64] feature: "ide-turn-rewind-snapshot" entry_points: ["jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/ui/ChatToolWindow.kt", "jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts"] source_globs: ["jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/ui/ChatToolWindow.kt", "jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts", "jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/settings/JiuwenSwarmSettings.kt"] @@ -44,3 +44,11 @@ JetBrains 侧入口是 ChatToolWindow 的 webview 消息处理分支:消息的 Sources / 来源:[jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/ui/ChatToolWindow.kt:L486–L512](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/ui/ChatToolWindow.kt#L486-L512), [jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L26–L64](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts#L26-L64) + + +**快照采集与回退行为** + +JetBrains 插件在 chat.tool_call/chat.tool_update 事件中,仅当 rewindEnabled 为 true 且工具名为 str_replace_editor/write_file/create_file/edit_file 时,按 file_path/path 取路径,每轮仅对首次出现的路径采集一次快照;文件不存在或读取抛异常时均记为 null(注释称 null 表示文件原本不存在,但 L641-L646 的 catch 分支在读取失败时同样存 null)。回退(webview 消息 "rewind")对 null 快照的现存文件执行删除,对非 null 快照仅当 VFS 中仍能找到该文件时写回原内容。VS Code 侧 DiffApplier.ts 维护同构的 currentTurnSnapshots/lastTurnSnapshots 结构,ensureSnapshot 同样在读取失败时存 null,并由 promoteSnapshots 在 chat.final 时晋升。 + +Sources / 来源:[jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/ui/ChatToolWindow.kt:L627–L649](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/ui/ChatToolWindow.kt#L627-L649), [jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/ui/ChatToolWindow.kt:L486–L512](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/ui/ChatToolWindow.kt#L486-L512), [jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts:L32–L64](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/vscode-extension/src/editor/DiffApplier.ts#L32-L64) + diff --git a/knowledge/repos/jiuwenswarm/components/ide-vscode/_index.md b/knowledge/repos/jiuwenswarm/components/ide-vscode/_index.md index 73d43dba..af9fee0f 100644 --- a/knowledge/repos/jiuwenswarm/components/ide-vscode/_index.md +++ b/knowledge/repos/jiuwenswarm/components/ide-vscode/_index.md @@ -22,3 +22,5 @@ sources: [] - [ide-vscode:VS Code 聊天面板与终端命令镜像](knowledge.md) - [IDE 终端命令镜像执行(VS Code 扩展与 JetBrains 插件)](feature-ide-terminal-command-mirror.md) + +- [IDE 终端命令镜像执行:实现深读](feature-depth-ide-terminal-command-mirror.md) diff --git a/knowledge/repos/jiuwenswarm/components/ide-vscode/feature-ide-terminal-command-mirror.md b/knowledge/repos/jiuwenswarm/components/ide-vscode/feature-ide-terminal-command-mirror.md index 1697672d..b7e32d86 100644 --- a/knowledge/repos/jiuwenswarm/components/ide-vscode/feature-ide-terminal-command-mirror.md +++ b/knowledge/repos/jiuwenswarm/components/ide-vscode/feature-ide-terminal-command-mirror.md @@ -1,10 +1,10 @@ --- title: "IDE 终端命令镜像执行(VS Code 扩展与 JetBrains 插件)" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/terminal/TerminalManager.ts:L5-L18, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/terminal/TerminalManager.kt:L49-L61, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/ui/ChatPanel.ts:L408-L418] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/terminal/TerminalManager.ts:L5-L18, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/terminal/TerminalManager.kt:L49-L61, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/ui/ChatPanel.ts:L408-L418, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/terminal/TerminalManager.ts:L9-L27, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/terminal/TerminalManager.ts:L34-L47, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/vscode-extension/src/ui/ChatPanel.ts:L354-L418, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/terminal/TerminalManager.kt:L40-L43, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/terminal/TerminalManager.kt:L10-L38, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/terminal/TerminalManager.kt:L44-L58] feature: "ide-terminal-command-mirror" entry_points: ["jiuwenswarm/channels/ide/packages/vscode-extension/src/terminal/TerminalManager.ts", "jiuwenswarm/channels/ide/packages/vscode-extension/src/ui/ChatPanel.ts"] source_globs: ["jiuwenswarm/channels/ide/packages/vscode-extension/src/terminal/TerminalManager.ts", "jiuwenswarm/channels/ide/packages/vscode-extension/src/ui/ChatPanel.ts", "jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/terminal/TerminalManager.kt"] @@ -30,3 +30,35 @@ Inference / 设计推断(非作者历史意图): Sources / 来源:[jiuwenswarm/channels/ide/packages/vscode-extension/src/ui/ChatPanel.ts:L408–L418](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/vscode-extension/src/ui/ChatPanel.ts#L408-L418) + + +**TerminalManager 模块契约(VS Code)** + +VS Code 扩展的 `terminal/TerminalManager.ts` 导出三个函数:`runCommand(command: string, cwd?: string): void` 在名为 JiuwenSwarm 的终端中执行命令,首次调用时惰性创建终端,之后 `show()` 并 `sendText(command)`;`disposeTerminal(): void` 释放并清空缓存的终端引用;`extractCommand(payload)` 从工具调用负载中提取命令字符串,找不到时返回 undefined。 + +Sources / 来源:[jiuwenswarm/channels/ide/packages/vscode-extension/src/terminal/TerminalManager.ts:L9–L27](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/vscode-extension/src/terminal/TerminalManager.ts#L9-L27), [jiuwenswarm/channels/ide/packages/vscode-extension/src/terminal/TerminalManager.ts:L34–L47](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/vscode-extension/src/terminal/TerminalManager.ts#L34-L47) + + + +**ChatPanel 中的命令镜像数据流** + +ChatPanel 处理服务器消息时,对 `event_type === 'chat.tool_call'` 且工具名为 `bash` 或 `run_command` 的调用进行镜像:先读取配置 `runCommandsInTerminal`(默认 true),为真时调用 `extractCommand(payload)` 提取命令,仅当提取结果非空时调用 `runCommand(cmd)` 在 IDE 终端执行,并输出 `TERM →` 调试日志。该分支位于文件编辑工具调用处理之后,同一个 tool_call 事件内。 + +Sources / 来源:[jiuwenswarm/channels/ide/packages/vscode-extension/src/ui/ChatPanel.ts:L354–L418](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/vscode-extension/src/ui/ChatPanel.ts#L354-L418) + + + +**runCommandsInTerminal 开关** + +VS Code 端在 ChatPanel 处理 `chat.tool_call` 时读取工作区配置 `jiuwenswarm.runCommandsInTerminal`,调用点传入回退值 `cfg.get('runCommandsInTerminal', true)`;为真且 `extractCommand` 提取到非空命令时才镜像执行。JetBrains 端在 `runCommand` 开头读取 `JiuwenSwarmSettings.instance().runCommandsInTerminal`,为 false 时直接 return;所示代码未包含该设置的定义或默认值,其未配置时的取值无法从本片段确定。 + +Sources / 来源:[jiuwenswarm/channels/ide/packages/vscode-extension/src/ui/ChatPanel.ts:L408–L418](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/vscode-extension/src/ui/ChatPanel.ts#L408-L418), [jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/terminal/TerminalManager.kt:L40–L43](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/terminal/TerminalManager.kt#L40-L43) + + + +**反射集成与容错取舍(JetBrains)** + +JetBrains 端通过反射查找 `org.jetbrains.plugins.terminal.TerminalView` 等类,代码注释明说这是为了在构建期缺少 Terminal 插件时仍可编译(运行期随 IDE 捆绑)。代价是:`init` 中任一反射查找失败只记录一条 info 日志("terminal integration disabled"),后续 `runCommand` 因方法句柄为 null 直接 return,集成静默降级;查找既有 widget 时的标题反射失败按 false 处理并继续,可能导致重复创建名为 JiuwenSwarm 的终端。 + +Sources / 来源:[jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/terminal/TerminalManager.kt:L10–L38](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/terminal/TerminalManager.kt#L10-L38), [jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/terminal/TerminalManager.kt:L44–L58](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/jetbrains-plugin/src/main/kotlin/com/jiuwenswarm/plugin/terminal/TerminalManager.kt#L44-L58) + diff --git a/knowledge/repos/jiuwenswarm/components/launch/knowledge.md b/knowledge/repos/jiuwenswarm/components/launch/knowledge.md index af8dcdf3..4982d2ae 100644 --- a/knowledge/repos/jiuwenswarm/components/launch/knowledge.md +++ b/knowledge/repos/jiuwenswarm/components/launch/knowledge.md @@ -1,10 +1,10 @@ --- title: "launch 组件基础:桌面外壳 desktop_app 的启动编排" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/desktop/desktop_app.py:L1230-L1284, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/desktop/desktop_app.py:L1287-L1427, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:docs/zh/desktop-electron-packaging.md:L216-L232, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/desktop/desktop_app.py:L340-L381, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/desktop/desktop_app.py:L443-L492, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:docs/zh/desktop-electron-packaging.md:L29-L41, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/desktop/desktop_app.py:L1087-L1137, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/desktop/desktop_app.py:L1693-L1904, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/desktop/desktop_app.py:L710-L774, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/desktop/desktop_app.py:L1230-L1278, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/desktop/desktop_app.py:L1287-L1389] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/desktop/desktop_app.py:L1230-L1284, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/desktop/desktop_app.py:L1287-L1427, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:docs/zh/desktop-electron-packaging.md:L216-L232, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/desktop/desktop_app.py:L340-L381, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/desktop/desktop_app.py:L443-L492, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:docs/zh/desktop-electron-packaging.md:L29-L41, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/desktop/desktop_app.py:L1087-L1137, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/desktop/desktop_app.py:L1693-L1904, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/desktop/desktop_app.py:L710-L774, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/desktop/desktop_app.py:L1230-L1278, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/desktop/desktop_app.py:L1287-L1389, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:docs/zh/desktop-electron-packaging.md:L291-L297, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:docs/zh/desktop-electron-packaging.md:L77-L79, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/test_debug_launcher.py:L15-L27] --- # launch 组件基础:桌面外壳 desktop_app 的启动编排 @@ -41,3 +41,11 @@ _WindowApi 是暴露给 WebView 内 JS 的桥接对象:一部分方法(如 m Sources / 来源:[jiuwenswarm/channels/desktop/desktop_app.py:L710–L774](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/desktop/desktop_app.py#L710-L774), [jiuwenswarm/channels/desktop/desktop_app.py:L1230–L1278](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/desktop/desktop_app.py#L1230-L1278), [jiuwenswarm/channels/desktop/desktop_app.py:L1287–L1389](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/desktop/desktop_app.py#L1287-L1389) + + +**怎样验证** + +桌面打包交接文档(docs/zh/desktop-electron-packaging.md §8)记录了 Python 侧契约测试命令:`uv run pytest tests/unit/test_electron_browser_target.py` 覆盖 Electron 子进程 argv/env 透传,并用源码断言测试 `test_electron_waits_for_navigated_cdp_target_before_starting_services` 保护启动顺序不变量;同节还列出 `tests/unit_tests/test_desktop_port_resolve.py`(dotenv 保留键)。这是文档化的手动验证入口,本输入未包含这些测试的源码,也不证明它们已运行或通过。此外,tests/unit_tests/test_debug_launcher.py 顶部直接从 `jiuwenswarm.start_services` 导入 `_parse_args` 与 `_validate_args`,说明服务启动的参数校验分支被该调试启动器单元测试模块作为被测对象引用。 + +Sources / 来源:[docs/zh/desktop-electron-packaging.md:L291–L297](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/docs/zh/desktop-electron-packaging.md#L291-L297), [docs/zh/desktop-electron-packaging.md:L77–L79](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/docs/zh/desktop-electron-packaging.md#L77-L79), [tests/unit_tests/test_debug_launcher.py:L15–L27](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/test_debug_launcher.py#L15-L27) + diff --git a/knowledge/repos/jiuwenswarm/components/observability/knowledge.md b/knowledge/repos/jiuwenswarm/components/observability/knowledge.md index bebc6db2..c954e82e 100644 --- a/knowledge/repos/jiuwenswarm/components/observability/knowledge.md +++ b/knowledge/repos/jiuwenswarm/components/observability/knowledge.md @@ -1,10 +1,10 @@ --- title: "JiuwenSwarm 可观测性:轨迹存储路由、有界写入与每会话 SQLite(jiuwenswarm/observability)" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/observability/store.py:L549-L601, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/observability/store.py:L737-L788, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/observability/config.py:L27-L32, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/observability/sink.py:L640-L650, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/observability/sink.py:L905-L919, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/observability/config.py:L82-L99, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/observability/sink.py:L759-L794, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/observability/config.py:L16-L32, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/observability/config.py:L126-L154, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/observability/config.py:L64-L69, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/observability/config.py:L72-L79, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/observability/test_trace_store.py:L289-L311, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/observability/test_trace_store.py:L425-L449, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/agentserver/test_trajectory_runtime_wiring.py:L214-L246, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/agentserver/test_trajectory_runtime_wiring.py:L379-L412] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/observability/store.py:L549-L601, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/observability/store.py:L737-L788, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/observability/config.py:L27-L32, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/observability/sink.py:L640-L650, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/observability/sink.py:L905-L919, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/observability/config.py:L82-L99, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/observability/sink.py:L759-L794, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/observability/config.py:L16-L32, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/observability/config.py:L126-L154, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/observability/config.py:L64-L69, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/observability/config.py:L72-L79, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/observability/test_trace_store.py:L289-L311, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/observability/test_trace_store.py:L425-L449, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/agentserver/test_trajectory_runtime_wiring.py:L214-L246, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/agentserver/test_trajectory_runtime_wiring.py:L379-L412, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/observability/sink.py:L479-L494, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/observability/sink.py:L821-L866] --- # JiuwenSwarm 可观测性:轨迹存储路由、有界写入与每会话 SQLite(jiuwenswarm/observability) @@ -41,3 +41,11 @@ tests/unit_tests/observability/test_trace_store.py 直接驱动 TrajectoryStore. Sources / 来源:[tests/unit_tests/observability/test_trace_store.py:L289–L311](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/observability/test_trace_store.py#L289-L311), [tests/unit_tests/observability/test_trace_store.py:L425–L449](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/observability/test_trace_store.py#L425-L449), [tests/unit_tests/agentserver/test_trajectory_runtime_wiring.py:L214–L246](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/agentserver/test_trajectory_runtime_wiring.py#L214-L246), [tests/unit_tests/agentserver/test_trajectory_runtime_wiring.py:L379–L412](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/agentserver/test_trajectory_runtime_wiring.py#L379-L412) + + +**轨迹消费入口与延迟载荷校验** + +TrajectorySessionSinkRouter 对外提供 consume / consume_snapshot / consume_stream_frame 三个常量开销入口,各自把记录以 final/snapshot/frame 类型做一次有界入队;路由线程再按会话转发给每会话的 TrajectoryRecordSink。载荷类型校验发生在写入线程:记录经 TraceRecordData.from_core_record / from_core_snapshot 转换,流帧经 StreamFrameData.from_core_frame 转换,坏记录只计入 failed 计数而不使整批失败。 + +Sources / 来源:[jiuwenswarm/observability/sink.py:L640–L650](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/observability/sink.py#L640-L650), [jiuwenswarm/observability/sink.py:L479–L494](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/observability/sink.py#L479-L494), [jiuwenswarm/observability/sink.py:L821–L866](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/observability/sink.py#L821-L866) + diff --git a/knowledge/repos/jiuwenswarm/components/packaging-deploy/knowledge-packaging-deploy.md b/knowledge/repos/jiuwenswarm/components/packaging-deploy/knowledge-packaging-deploy.md index 828cd6e6..4dace2de 100644 --- a/knowledge/repos/jiuwenswarm/components/packaging-deploy/knowledge-packaging-deploy.md +++ b/knowledge/repos/jiuwenswarm/components/packaging-deploy/knowledge-packaging-deploy.md @@ -1,10 +1,10 @@ --- title: "packaging-deploy:冻结入口、容器与 yuanrong 部署链路" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:scripts/jiuwenswarm_exe_entry.py:L126-L164, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:scripts/jiuwenswarm_exe_entry.py:L628-L653, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:deploy/yuanrong/args_handler.sh:L46-L67, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:Makefile:L125-L155, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:deploy/yuanrong/web_handler.sh:L126-L152, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:deploy/yuanrong/web_handler.sh:L184-L197, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:scripts/build-runtimes.sh:L3-L7, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:scripts/jiuwenswarm_exe_entry.py:L599-L655, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:scripts/jiuwenswarm_exe_entry.py:L328-L342, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:Dockerfile.claw:L26-L84, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:deploy/yuanrong/args_handler.sh:L46-L56, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:deploy/yuanrong/web_handler.sh:L5-L18, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:deploy/yuanrong/web_handler.sh:L205-L217, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:Dockerfile.claw:L89-L100] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:scripts/jiuwenswarm_exe_entry.py:L126-L164, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:scripts/jiuwenswarm_exe_entry.py:L628-L653, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:deploy/yuanrong/args_handler.sh:L46-L67, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:Makefile:L125-L155, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:deploy/yuanrong/web_handler.sh:L126-L152, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:deploy/yuanrong/web_handler.sh:L184-L197, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:scripts/build-runtimes.sh:L3-L7, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:scripts/jiuwenswarm_exe_entry.py:L599-L655, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:scripts/jiuwenswarm_exe_entry.py:L328-L342, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:Dockerfile.claw:L26-L84, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:deploy/yuanrong/args_handler.sh:L46-L56, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:deploy/yuanrong/web_handler.sh:L5-L18, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:deploy/yuanrong/web_handler.sh:L205-L217, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:Dockerfile.claw:L89-L100, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:scripts/build-runtimes.psm1:L15-L26, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:scripts/build-runtimes.sh:L11-L13] --- # packaging-deploy:冻结入口、容器与 yuanrong 部署链路 @@ -41,3 +41,11 @@ yuanrong deploy.sh 支持 `up|down|restart` 命令与 `jiuwenswarm|gateway|web` Sources / 来源:[deploy/yuanrong/args_handler.sh:L46–L56](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/deploy/yuanrong/args_handler.sh#L46-L56), [deploy/yuanrong/web_handler.sh:L5–L18](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/deploy/yuanrong/web_handler.sh#L5-L18), [deploy/yuanrong/web_handler.sh:L205–L217](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/deploy/yuanrong/web_handler.sh#L205-L217), [Dockerfile.claw:L89–L100](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/Dockerfile.claw#L89-L100) + + +**Node/uv 捆绑的构建常量与默认值** + +Windows 打包链的运行时捆绑开关集中在一个函数中:BUNDLE_NODE、BUNDLE_UV 默认 "1",NODE_VERSION 默认 "v22.11.0",三者均可被同名环境变量覆盖,且这些默认值在模块中只出现一次、由两条打包脚本通过该函数读取。macOS 侧的 build-runtimes.sh 定义同样的默认:NODE_VERSION 默认 v22.11.0、BUNDLE_NODE 默认 1(0 跳过内置 node),也可用环境变量覆盖。 + +Sources / 来源:[scripts/build-runtimes.psm1:L15–L26](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/scripts/build-runtimes.psm1#L15-L26), [scripts/build-runtimes.sh:L11–L13](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/scripts/build-runtimes.sh#L11-L13) + diff --git a/knowledge/repos/jiuwenswarm/components/protocols/knowledge-protocols.md b/knowledge/repos/jiuwenswarm/components/protocols/knowledge-protocols.md index eaec12c8..028846ed 100644 --- a/knowledge/repos/jiuwenswarm/components/protocols/knowledge-protocols.md +++ b/knowledge/repos/jiuwenswarm/components/protocols/knowledge-protocols.md @@ -1,10 +1,10 @@ --- title: "jiuwenswarm/common/e2a:E2A 统一请求/响应协议组件知识" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:docs/zh/A2A.md:L134-L152, "openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:docs/zh/ACP插件使用.md:L60-L86", openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/common/e2a/gateway_normalize.py:L197-L213, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/common/e2a/gateway_normalize.py:L138-L213, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/common/e2a/adapters.py:L42-L124, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:docs/zh/E2A-protocol.md:L21-L25, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/common/e2a/wire_codec.py:L1-L3, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/common/e2a/gateway_normalize.py:L38-L59, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/common/e2a/gateway_normalize.py:L116-L135, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/common/e2a/agent_compat.py:L28-L37, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/common/e2a/gateway_normalize.py:L61-L65, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/common/e2a/gateway_normalize.py:L93-L113, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/common/e2a/constants.py:L93-L116] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:docs/zh/A2A.md:L134-L152, "openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:docs/zh/ACP插件使用.md:L60-L86", openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/common/e2a/gateway_normalize.py:L197-L213, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/common/e2a/gateway_normalize.py:L138-L213, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/common/e2a/adapters.py:L42-L124, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:docs/zh/E2A-protocol.md:L21-L25, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/common/e2a/wire_codec.py:L1-L3, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/common/e2a/gateway_normalize.py:L38-L59, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/common/e2a/gateway_normalize.py:L116-L135, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/common/e2a/agent_compat.py:L28-L37, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/common/e2a/gateway_normalize.py:L61-L65, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/common/e2a/gateway_normalize.py:L93-L113, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/common/e2a/constants.py:L93-L116, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/common/e2a/gateway_normalize.py:L41-L59, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/common/e2a/gateway_normalize.py:L487-L503, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/common/e2a/gateway_normalize.py:L559-L572, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/e2a/test_gateway_normalize.py:L23-L46] --- # jiuwenswarm/common/e2a:E2A 统一请求/响应协议组件知识 @@ -43,3 +43,11 @@ Sources / 来源:[jiuwenswarm/common/e2a/gateway_normalize.py:L38–L59](https Sources / 来源:[jiuwenswarm/common/e2a/gateway_normalize.py:L61–L65](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/common/e2a/gateway_normalize.py#L61-L65), [jiuwenswarm/common/e2a/gateway_normalize.py:L93–L113](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/common/e2a/gateway_normalize.py#L93-L113), [jiuwenswarm/common/e2a/constants.py:L93–L116](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/common/e2a/constants.py#L93-L116) + + +**chat.delta identity passthrough whitelist survives the E2A round trip** + +Streaming `chat.delta` frames are converted to `E2AResponse` bodies by copying a fixed whitelist of keys (`rid`, `execution_id`, `turn_request_id`, `cross_session`, `proactive_type`, etc.) alongside `delta_kind`/`delta`, and the reverse conversion `e2a_response_to_agent_chunk` restores exactly the same key set, so round-identity fields (execution binding, cross-session and proactive markers) survive the Gateway↔AgentServer wire. Unit tests in `tests/unit_tests/e2a/test_gateway_normalize.py` exercise this round trip against `WebChannel._build_event_payload` for execution, cross-session, phase-order and proactive fields. + +Sources / 来源:[jiuwenswarm/common/e2a/gateway_normalize.py:L41–L59](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/common/e2a/gateway_normalize.py#L41-L59), [jiuwenswarm/common/e2a/gateway_normalize.py:L487–L503](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/common/e2a/gateway_normalize.py#L487-L503), [jiuwenswarm/common/e2a/gateway_normalize.py:L559–L572](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/common/e2a/gateway_normalize.py#L559-L572), [tests/unit_tests/e2a/test_gateway_normalize.py:L23–L46](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/e2a/test_gateway_normalize.py#L23-L46) + diff --git a/knowledge/repos/jiuwenswarm/components/sandbox-runtime/knowledge.md b/knowledge/repos/jiuwenswarm/components/sandbox-runtime/knowledge.md index 6b037251..f90c00ea 100644 --- a/knowledge/repos/jiuwenswarm/components/sandbox-runtime/knowledge.md +++ b/knowledge/repos/jiuwenswarm/components/sandbox-runtime/knowledge.md @@ -1,10 +1,10 @@ --- title: "sandbox-runtime(JiuwenBox 服务与推理隐私代理)" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenbox/src/jiuwenbox/server/app.py:L260-L330, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenbox/src/jiuwenbox/server/app.py:L332-L402, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenbox/src/jiuwenbox/server/app.py:L207-L224, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenbox/src/jiuwenbox/server/app.py:L83-L114, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenbox/src/jiuwenbox/server/app.py:L227-L257, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenbox/src/jiuwenbox/proxy/inference_privacy_proxy_manager.py:L581-L633, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenbox/src/jiuwenbox/proxy/inference_privacy_proxy.py:L119-L123, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenbox/src/jiuwenbox/proxy/inference_privacy_proxy.py:L189-L196, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenbox/src/jiuwenbox/proxy/inference_privacy_proxy_manager.py:L501-L510, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenbox/src/jiuwenbox/proxy/inference_privacy_proxy.py:L294-L306, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenbox/src/jiuwenbox/proxy/inference_privacy_proxy.py:L167-L196, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenbox/src/jiuwenbox/server/app.py:L275-L295, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenbox/src/jiuwenbox/proxy/inference_privacy_proxy.py:L130-L133, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenbox/src/jiuwenbox/proxy/inference_privacy_proxy_manager.py:L204-L210, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenbox/src/jiuwenbox/proxy/inference_privacy_proxy_manager.py:L164-L183, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenbox/src/jiuwenbox/proxy/inference_privacy_proxy_manager.py:L557-L579] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenbox/src/jiuwenbox/server/app.py:L260-L330, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenbox/src/jiuwenbox/server/app.py:L332-L402, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenbox/src/jiuwenbox/server/app.py:L207-L224, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenbox/src/jiuwenbox/server/app.py:L83-L114, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenbox/src/jiuwenbox/server/app.py:L227-L257, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenbox/src/jiuwenbox/proxy/inference_privacy_proxy_manager.py:L581-L633, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenbox/src/jiuwenbox/proxy/inference_privacy_proxy.py:L119-L123, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenbox/src/jiuwenbox/proxy/inference_privacy_proxy.py:L189-L196, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenbox/src/jiuwenbox/proxy/inference_privacy_proxy_manager.py:L501-L510, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenbox/src/jiuwenbox/proxy/inference_privacy_proxy.py:L294-L306, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenbox/src/jiuwenbox/proxy/inference_privacy_proxy.py:L167-L196, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenbox/src/jiuwenbox/server/app.py:L275-L295, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenbox/src/jiuwenbox/proxy/inference_privacy_proxy.py:L130-L133, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenbox/src/jiuwenbox/proxy/inference_privacy_proxy_manager.py:L204-L210, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenbox/src/jiuwenbox/proxy/inference_privacy_proxy_manager.py:L164-L183, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenbox/src/jiuwenbox/proxy/inference_privacy_proxy_manager.py:L557-L579, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenbox/tests/integration/test_inference_privacy_proxy.py:L1225-L1241, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenbox/src/jiuwenbox/proxy/inference_privacy_proxy_manager.py:L277-L292] --- # sandbox-runtime(JiuwenBox 服务与推理隐私代理) @@ -51,3 +51,11 @@ Sources / 来源:[jiuwenbox/src/jiuwenbox/proxy/inference_privacy_proxy.py:L16 Sources / 来源:[jiuwenbox/src/jiuwenbox/proxy/inference_privacy_proxy.py:L130–L133](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenbox/src/jiuwenbox/proxy/inference_privacy_proxy.py#L130-L133), [jiuwenbox/src/jiuwenbox/proxy/inference_privacy_proxy_manager.py:L204–L210](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenbox/src/jiuwenbox/proxy/inference_privacy_proxy_manager.py#L204-L210), [jiuwenbox/src/jiuwenbox/proxy/inference_privacy_proxy_manager.py:L164–L183](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenbox/src/jiuwenbox/proxy/inference_privacy_proxy_manager.py#L164-L183), [jiuwenbox/src/jiuwenbox/proxy/inference_privacy_proxy_manager.py:L557–L579](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenbox/src/jiuwenbox/proxy/inference_privacy_proxy_manager.py#L557-L579) + + +**REST 代理路由生命周期:POST /api/v1/proxies 创建后经 /start 启动** + +集成测试演示了 REST 层的路由生命周期入口:先 POST /api/v1/proxies 提交 {"path_prefix": ..., "target_endpoint": ...} 创建路由,再 POST /api/v1/proxies/{name}/start,断言返回 200 且响应 JSON 的 state 为 "running",随后经代理端口验证请求被真实转发。底层 manager 的 create_proxy(name, config) 在全局代理 listen_port==0 时抛 ValueError("...listen_port=0 (disabled)..."),仅当非零端口才创建路由并返回 {name, state: "stopped", created_at}。 + +Sources / 来源:[jiuwenbox/tests/integration/test_inference_privacy_proxy.py:L1225–L1241](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenbox/tests/integration/test_inference_privacy_proxy.py#L1225-L1241), [jiuwenbox/src/jiuwenbox/proxy/inference_privacy_proxy_manager.py:L277–L292](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenbox/src/jiuwenbox/proxy/inference_privacy_proxy_manager.py#L277-L292) + diff --git a/knowledge/repos/jiuwenswarm/components/symphony-orchestration/knowledge.md b/knowledge/repos/jiuwenswarm/components/symphony-orchestration/knowledge.md index 4ea133b3..80be739a 100644 --- a/knowledge/repos/jiuwenswarm/components/symphony-orchestration/knowledge.md +++ b/knowledge/repos/jiuwenswarm/components/symphony-orchestration/knowledge.md @@ -1,10 +1,10 @@ --- title: "Symphony orchestration service (jiuwenswarm/symphony/service.py) 基础知识页" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/symphony/service.py:L210-L224, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/symphony/service.py:L636-L672, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/symphony/service.py:L449-L472, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/symphony/service.py:L515-L533, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/symphony/service.py:L937-L998, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/symphony/service.py:L80-L84, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/symphony/config.py:L12-L33, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/symphony/config.py:L112-L151, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/symphony/config.py:L240-L273, "openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:docs/zh/Symphony-技能编排与分发.md:L93-L99", openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/symphony/service.py:L1188-L1214, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/symphony/service.py:L1252-L1311] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/symphony/service.py:L210-L224, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/symphony/service.py:L636-L672, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/symphony/service.py:L449-L472, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/symphony/service.py:L515-L533, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/symphony/service.py:L937-L998, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/symphony/service.py:L80-L84, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/symphony/config.py:L12-L33, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/symphony/config.py:L112-L151, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/symphony/config.py:L240-L273, "openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:docs/zh/Symphony-技能编排与分发.md:L93-L99", openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/symphony/service.py:L1188-L1214, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/symphony/service.py:L1252-L1311, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/symphony/test_graph_state.py:L34-L49, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/symphony/test_graph_state.py:L52-L67, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/test_config.py:L107-L134] --- # Symphony orchestration service (jiuwenswarm/symphony/service.py) 基础知识页 @@ -41,3 +41,11 @@ Sources / 来源:[jiuwenswarm/symphony/config.py:L12–L33](https://github.com Sources / 来源:[docs/zh/Symphony-技能编排与分发.md:L93–L99](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/docs/zh/Symphony-%E6%8A%80%E8%83%BD%E7%BC%96%E6%8E%92%E4%B8%8E%E5%88%86%E5%8F%91.md#L93-L99), [jiuwenswarm/symphony/service.py:L1188–L1214](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/symphony/service.py#L1188-L1214), [jiuwenswarm/symphony/service.py:L1252–L1311](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/symphony/service.py#L1252-L1311) + + +**graph_state 与 evolution 开关的既有单元测试** + +既有辅助层单元测试(未在本次输入中运行):tests/unit_tests/symphony/test_graph_state.py 直接构造 CapabilityDescriptor 与 GraphStateBuilder,断言 next_state 生成 schema_version "Symphony-graph-state-v2"、能力哈希键映射为相对路径,并覆盖从 v1 旧 skill_md_sha256 的一次性迁移读取。tests/unit_tests/test_config.py 的 test_symphony_evolution_getter_reads_only_passed_switches 用 monkeypatch 把全局配置与完整解析器替换为 pytest.fail,验证 get_symphony_evolution_enabled 只读取传入的开关字典、不触发配置加载。二者均为 helper 单元测试,不是对 SwarmSymphonyService 运行时行为的端到端验证。 + +Sources / 来源:[tests/unit_tests/symphony/test_graph_state.py:L34–L49](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/symphony/test_graph_state.py#L34-L49), [tests/unit_tests/symphony/test_graph_state.py:L52–L67](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/symphony/test_graph_state.py#L52-L67), [tests/unit_tests/test_config.py:L107–L134](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/test_config.py#L107-L134) + diff --git a/knowledge/repos/jiuwenswarm/components/web-frontend/_index.md b/knowledge/repos/jiuwenswarm/components/web-frontend/_index.md index 430b2d95..8229a05d 100644 --- a/knowledge/repos/jiuwenswarm/components/web-frontend/_index.md +++ b/knowledge/repos/jiuwenswarm/components/web-frontend/_index.md @@ -116,3 +116,25 @@ sources: [] - [Web 资产发布流程(prepare/commit/轮询/提交锁)](feature-web-asset-publish-flow.md) - [Web 前端中英双语 i18n 初始化(jiuwenswarm/channels/web/frontend)](feature-web-i18n-zh-en.md) - [RSI 自我改进实验页(创建/列表/配置回显)](feature-rsi-experiment-ui.md) + +- [Chat Session Stats Bar and Per-Turn Mini Charts:实现深读](feature-depth-chat-session-stats-dashboard.md) + +- [代码模式分支选择器(初始化/切换/创建分支):实现深读](feature-depth-code-mode-branch-selector.md) + +- [提交/推送对话框(commit、push、commit_push):实现深读](feature-depth-code-mode-commit-push.md) + +- [上下文占用指示器(环形/悬浮提示/明细弹层):实现深读](feature-depth-context-usage-indicator.md) + +- [Vite Dev WS Traffic Logger (/__dev/ws-log):实现深读](feature-depth-dev-ws-traffic-logger.md) + +- [增量 ESLint 门禁(相对基线只报新增诊断):实现深读](feature-depth-frontend-incremental-lint-gate.md) + +- [RSI 自我改进实验页(创建/列表/配置回显):实现深读](feature-depth-rsi-experiment-ui.md) + +- [Session Share-Image Export (Job Registry + Headless Renderer):实现深读](feature-depth-share-image-export.md) + +- [Web 资产发布流程(prepare/commit/轮询/提交锁):实现深读](feature-depth-web-asset-publish-flow.md) + +- [Web 前端中英双语 i18n 初始化:实现深读](feature-depth-web-i18n-zh-en.md) + +- [Web 通道本机目录/可执行文件选择器(跨平台后端链):实现深读](feature-depth-web-native-directory-picker.md) diff --git a/knowledge/repos/jiuwenswarm/components/web-frontend/feature-chat-session-stats-dashboard.md b/knowledge/repos/jiuwenswarm/components/web-frontend/feature-chat-session-stats-dashboard.md index d86627eb..29c09961 100644 --- a/knowledge/repos/jiuwenswarm/components/web-frontend/feature-chat-session-stats-dashboard.md +++ b/knowledge/repos/jiuwenswarm/components/web-frontend/feature-chat-session-stats-dashboard.md @@ -1,10 +1,10 @@ --- title: "IDE Webview 会话统计栏与每轮迷你图(chat.html)" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/shared-webview/chat.html:L4453-L4524, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/shared-webview/chat.html:L4475-L4489, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/shared-webview/chat.html:L4492-L4524, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/shared-webview/chat.html:L4495-L4521, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/shared-webview/chat.html:L4602-L4628, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/shared-webview/chat.html:L4475-L4477, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/shared-webview/chat.html:L4494-L4496, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/shared-webview/chat.html:L4626-L4628, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/shared-webview/chat.html:L4503-L4516, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/shared-webview/chat.html:L4517-L4521, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/shared-webview/chat.html:L4691-L4697] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/shared-webview/chat.html:L4453-L4524, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/shared-webview/chat.html:L4475-L4489, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/shared-webview/chat.html:L4492-L4524, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/shared-webview/chat.html:L4495-L4521, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/shared-webview/chat.html:L4602-L4628, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/shared-webview/chat.html:L4475-L4477, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/shared-webview/chat.html:L4494-L4496, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/shared-webview/chat.html:L4626-L4628, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/shared-webview/chat.html:L4503-L4516, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/shared-webview/chat.html:L4517-L4521, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/shared-webview/chat.html:L4691-L4697, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/shared-webview/chat.html:L4437-L4466, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/ide/packages/shared-webview/chat.html:L4451-L4451] feature: "chat-session-stats-dashboard" entry_points: ["jiuwenswarm/channels/ide/packages/shared-webview/chat.html"] source_globs: ["jiuwenswarm/channels/ide/packages/shared-webview/chat.html"] @@ -60,3 +60,11 @@ Sources / 来源:[jiuwenswarm/channels/ide/packages/shared-webview/chat.html:L Sources / 来源:[jiuwenswarm/channels/ide/packages/shared-webview/chat.html:L4503–L4516](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/shared-webview/chat.html#L4503-L4516), [jiuwenswarm/channels/ide/packages/shared-webview/chat.html:L4517–L4521](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/shared-webview/chat.html#L4517-L4521), [jiuwenswarm/channels/ide/packages/shared-webview/chat.html:L4691–L4697](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/shared-webview/chat.html#L4691-L4697) + + +**统计栏与迷你图展示的行为范围** + +统计栏在首轮完成后(totalTurns >= 1)显示会话级指标:Turns、Errors(仅在有错误时出现)、Tokens、LLM calls、Avg duration、Avg first token,以及条件出现的 Ctx Size(依赖 m.contextBytes 或 m.promptEstimatedTokens 非零)、Cost 与 TODO 进度(✓/◐/☐)芯片。Tokens 数值优先取宿主提供的 m.sessionTokens,但其为 0 或缺省时回退到本地累计的 s.totalTokens(`m.sessionTokens || s.totalTokens`,真值判断)。迷你图提供 Tokens/turn 与 Duration/turn 两组柱状图:每柱高度为 Math.max(6, Math.round(v / maxVal * 100)),即先对相对百分比取整再强制最小 6% 高度,分母 maxVal 由序列最大值与 1 取最大(Math.max(...values, 1))保证下界;柱色按该轮 outcome 映射,未知 outcome 用灰色 #6b7280。 + +Sources / 来源:[jiuwenswarm/channels/ide/packages/shared-webview/chat.html:L4437–L4466](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/shared-webview/chat.html#L4437-L4466), [jiuwenswarm/channels/ide/packages/shared-webview/chat.html:L4451–L4451](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/shared-webview/chat.html#L4451-L4451), [jiuwenswarm/channels/ide/packages/shared-webview/chat.html:L4503–L4516](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/shared-webview/chat.html#L4503-L4516), [jiuwenswarm/channels/ide/packages/shared-webview/chat.html:L4517–L4521](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/ide/packages/shared-webview/chat.html#L4517-L4521) + diff --git a/knowledge/repos/jiuwenswarm/components/web-frontend/feature-context-usage-indicator.md b/knowledge/repos/jiuwenswarm/components/web-frontend/feature-context-usage-indicator.md index 5e9c0273..ecd74d40 100644 --- a/knowledge/repos/jiuwenswarm/components/web-frontend/feature-context-usage-indicator.md +++ b/knowledge/repos/jiuwenswarm/components/web-frontend/feature-context-usage-indicator.md @@ -1,10 +1,10 @@ --- title: "上下文占用指示器(ContextUsageIndicator:环形触发器/悬浮提示/明细弹层)" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx:L152-L165, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx:L121-L140, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx:L273-L304, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx:L62-L77, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx:L142-L157, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/server/runtime/agent_adapter/interface_deep.py:L18649-L18701, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx:L19-L22, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx:L144-L164, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx:L233-L238, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx:L182-L201, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx:L218-L265, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/server/runtime/agent_adapter/interface_deep.py:L18666-L18701, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx:L142-L151] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx:L152-L165, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx:L121-L140, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx:L273-L304, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx:L62-L77, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx:L142-L157, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/server/runtime/agent_adapter/interface_deep.py:L18649-L18701, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx:L19-L22, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx:L144-L164, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx:L233-L238, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx:L182-L201, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx:L218-L265, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/server/runtime/agent_adapter/interface_deep.py:L18666-L18701, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx:L142-L151, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx:L142-L165, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx:L218-L245] feature: "context-usage-indicator" entry_points: ["jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.css", "jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx"] source_globs: ["jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.css", "jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx", "jiuwenswarm/server/runtime/agent_adapter/interface_deep.py", "jiuwenswarm/server/utils/stream_utils.py"] @@ -52,3 +52,19 @@ Sources / 来源:[jiuwenswarm/channels/web/frontend/src/components/ChatPanel/C Sources / 来源:[jiuwenswarm/server/runtime/agent_adapter/interface_deep.py:L18666–L18701](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/server/runtime/agent_adapter/interface_deep.py#L18666-L18701), [jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx:L142–L151](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx#L142-L151), [jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx:L233–L238](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx#L233-L238) + + +**前后端职责划分与数据流** + +数据流分两段。前端 `ContextUsageIndicator()` 是无 props 的纯消费组件:从 `chatStore.activeSessionId` 与 `sessionStore.runtimes[id].contextUsageSnapshot` 取数,仅在 mode 为 agent/team 且快照存在时渲染,快照的 `context_window`、`session_kv_cache_hit_rate` 与 `parts` 直接驱动环形弧长、悬浮提示与明细弹层(含按类别分段的 breakdown),弹层通过 createPortal 挂到 document.body 并基于触发按钮的 getBoundingClientRect 定位(tsx:62-77、142-165、218-245)。服务端侧 `JiuWenSwarmDeepAdapter.get_context_usage_event` 负责产出快照:非会话作用域适配器先委托/复用按会话适配器并在结束后逐出空闲适配器;会话作用域路径从 `react_agent.context_engine.get_context(session_id)` 取上下文,调用 agent-core 的 `build_context_usage_snapshot`(phase="post_compact")并经 `normalize_context_usage_payload` 归一化返回,异常保护仅覆盖快照构造与归一化这一段(interface_deep.py:18649-18701)。 + +Sources / 来源:[jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx:L62–L77](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx#L62-L77), [jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx:L142–L165](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx#L142-L165), [jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx:L218–L245](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx#L218-L245), [jiuwenswarm/server/runtime/agent_adapter/interface_deep.py:L18649–L18701](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/server/runtime/agent_adapter/interface_deep.py#L18649-L18701) + + + +**前后端职责划分与数据流** + +前端 `ContextUsageIndicator()` 是无 props 的纯消费组件:从 `chatStore.activeSessionId` 与 `sessionStore.runtimes[id].contextUsageSnapshot` 取数,仅在 mode 为 agent/team 且快照存在时渲染,快照的 `context_window`、`session_kv_cache_hit_rate` 与 `parts` 驱动环形弧长、悬浮提示与明细弹层,弹层经 createPortal 挂到 document.body 并按触发按钮的 getBoundingClientRect 定位。服务端 `JiuWenSwarmDeepAdapter.get_context_usage_event` 负责产出快照:非会话作用域适配器先委托按会话适配器并在结束后逐出空闲适配器;会话作用域路径从 `react_agent.context_engine.get_context(session_id)` 取上下文,调用 agent-core 的 `build_context_usage_snapshot`(phase="post_compact")并经 `normalize_context_usage_payload` 归一化返回。 + +Sources / 来源:[jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx:L62–L77](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx#L62-L77), [jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx:L142–L165](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx#L142-L165), [jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx:L218–L245](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/components/ChatPanel/ContextUsageIndicator.tsx#L218-L245), [jiuwenswarm/server/runtime/agent_adapter/interface_deep.py:L18649–L18701](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/server/runtime/agent_adapter/interface_deep.py#L18649-L18701) + diff --git a/knowledge/repos/jiuwenswarm/components/web-frontend/feature-rsi-experiment-ui.md b/knowledge/repos/jiuwenswarm/components/web-frontend/feature-rsi-experiment-ui.md index 5f54e67b..5773a5ad 100644 --- a/knowledge/repos/jiuwenswarm/components/web-frontend/feature-rsi-experiment-ui.md +++ b/knowledge/repos/jiuwenswarm/components/web-frontend/feature-rsi-experiment-ui.md @@ -1,10 +1,10 @@ --- title: "RSI 自我改进实验页(创建/列表/配置回显)" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/rsi/components/CreateExperimentDialog.tsx:L247-L316, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/rsi/artifact_adapter.py:L370-L398, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/rsi/artifact_adapter.py:L400-L434, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/rsi/featureConfig.ts:L3-L33, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/rsi/components/CreateExperimentDialog.tsx:L89-L103, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/rsi/components/ConfigInfoDialog.tsx:L28-L65] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/rsi/components/CreateExperimentDialog.tsx:L247-L316, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/rsi/artifact_adapter.py:L370-L398, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/rsi/artifact_adapter.py:L400-L434, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/rsi/featureConfig.ts:L3-L33, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/rsi/components/CreateExperimentDialog.tsx:L89-L103, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/rsi/components/ConfigInfoDialog.tsx:L28-L65, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/rsi/components/CreateExperimentDialog.tsx:L116-L157, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/rsi/components/CreateExperimentDialog.tsx:L195-L209, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/rsi/components/CreateExperimentDialog.tsx:L318-L319, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/rsi/test_paper_provider.py:L49-L130, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/rsi/test_artifact_files_service.py:L17-L44, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/rsi/test_artifact_files_service.py:L88-L100, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/rsi/RsiPage.tsx:L28-L56, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/rsi/RsiPage.tsx:L60-L78, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/agents/harness/common/rsi/artifact_adapter.py:L355-L368] feature: "rsi-experiment-ui" entry_points: ["jiuwenswarm/channels/web/frontend/src/features/rsi/RsiPage.tsx", "jiuwenswarm/channels/web/frontend/src/features/rsi/components/ConfigInfoDialog.tsx", "jiuwenswarm/channels/web/frontend/src/features/rsi/components/CreateExperimentDialog.tsx"] source_globs: ["jiuwenswarm/channels/web/frontend/src/features/rsi/RsiPage.tsx", "jiuwenswarm/channels/web/frontend/src/features/rsi/components/ConfigInfoDialog.tsx", "jiuwenswarm/channels/web/frontend/src/features/rsi/components/CreateExperimentDialog.tsx", "jiuwenswarm/agents/harness/common/rsi/artifact_adapter.py", "jiuwenswarm/channels/web/frontend/src/features/rsi/components/RsiDetail.tsx", "jiuwenswarm/channels/web/frontend/src/features/rsi/components/RsiRail.tsx", "jiuwenswarm/channels/web/frontend/src/features/rsi/rsiStore.ts", "jiuwenswarm/channels/web/frontend/src/features/rsi/featureConfig.ts", "jiuwenswarm/channels/web/frontend/src/features/rsi/types.ts", "jiuwenswarm/channels/web/frontend/src/features/rsi/styles/rsi.css", "jiuwenswarm/channels/web/frontend/src/features/rsi/components/RsiIntroduction.tsx", "jiuwenswarm/channels/web/frontend/src/features/rsi/mockData.ts", "jiuwenswarm/channels/web/frontend/src/features/rsi/rsiPresentation.ts", "jiuwenswarm/channels/web/frontend/src/features/rsi/components/RsiSelectedInfo.tsx", "jiuwenswarm/agents/harness/common/rsi/paper_provider.py", "jiuwenswarm/agents/harness/common/rsi/projector.py", "jiuwenswarm/channels/web/frontend/src/features/rsi/useRsiEvents.ts"] @@ -28,3 +28,37 @@ RSI 特性开关 featureConfig.ts 默认启用(rsiFeatureEnabled = true),n Sources / 来源:[jiuwenswarm/channels/web/frontend/src/features/rsi/featureConfig.ts:L3–L33](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/features/rsi/featureConfig.ts#L3-L33), [jiuwenswarm/channels/web/frontend/src/features/rsi/components/CreateExperimentDialog.tsx:L89–L103](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/features/rsi/components/CreateExperimentDialog.tsx#L89-L103), [jiuwenswarm/channels/web/frontend/src/features/rsi/components/ConfigInfoDialog.tsx:L28–L65](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/features/rsi/components/ConfigInfoDialog.tsx#L28-L65) + + +**创建弹窗的三分支表单** + +CreateExperimentDialog 用 useMemo 在每次字段变化时重算校验:HARNESS 分支必填 datasetFile 与 tester;PAPER 分支要求 optimizationInstruction 与 artifactPath 至少其一;PROGRAM 分支必填 artifactPath。切换到 PROGRAM 时重置 maxIterations 为 3 并清空 optimizationInstruction/webProxy,且 showMaxIterations = branch !== 'PROGRAM' 隐藏迭代字段。选择数据集路径后自动调用 rsiDatasetValidate(带 scenario/artifact_type),失败时按 valid=false 兜底。 + +Sources / 来源:[jiuwenswarm/channels/web/frontend/src/features/rsi/components/CreateExperimentDialog.tsx:L116–L157](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/features/rsi/components/CreateExperimentDialog.tsx#L116-L157), [jiuwenswarm/channels/web/frontend/src/features/rsi/components/CreateExperimentDialog.tsx:L195–L209](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/features/rsi/components/CreateExperimentDialog.tsx#L195-L209), [jiuwenswarm/channels/web/frontend/src/features/rsi/components/CreateExperimentDialog.tsx:L318–L319](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/features/rsi/components/CreateExperimentDialog.tsx#L318-L319) + + + +**现有单元测试入口(未执行)** + +两类 helper 单元测试存在于 tests/unit_tests/rsi/(本输入仅做符号定位,未执行)。test_paper_provider.py 用 FakeRuntime 替换 ManagerRuntime,断言传给 runtime 的 config/request 组件与 usage 台账记账;test_artifact_files_service.py 构造真实目录与 ZIP 文件,经 RsiArtifactFilesService.list_files/read_file 验证产物可浏览与可读(涉及文件系统,非纯函数断言),并在 L88-L100 断言 provider_best_artifact 对同一 best 节点取最新 artifact_index 引用。 + +Sources / 来源:[tests/unit_tests/rsi/test_paper_provider.py:L49–L130](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/rsi/test_paper_provider.py#L49-L130), [tests/unit_tests/rsi/test_artifact_files_service.py:L17–L44](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/rsi/test_artifact_files_service.py#L17-L44), [tests/unit_tests/rsi/test_artifact_files_service.py:L88–L100](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/rsi/test_artifact_files_service.py#L88-L100) + + + +**RsiPage 的列表加载与选中流程** + +RsiPage 是实验页主组件:挂载期间通过 useRsiEvents(true) 订阅推送事件,进入页面时用 loadList() 拉取实验列表;列表加载完成后若尚未选中任务,自动 selectTask 选中第一个任务。创建成功的回调 handleCreated 先 upsertListItem 把新任务写入列表,再 selectTask 切换到该任务;页面按是否有选中任务在 RsiRail+RsiDetail 与 RsiIntroduction 之间条件渲染。 + +Sources / 来源:[jiuwenswarm/channels/web/frontend/src/features/rsi/RsiPage.tsx:L28–L56](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/features/rsi/RsiPage.tsx#L28-L56), [jiuwenswarm/channels/web/frontend/src/features/rsi/RsiPage.tsx:L60–L78](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/features/rsi/RsiPage.tsx#L60-L78) + + + +**build_request 对 model/model_config 双契约的兼容** + +Inference / 设计推断(非作者历史意图): + +ArtifactEngineAdapter.build_request 在构造请求时同时兼容 agent-core 旧的 model_config 占位与新版 model 对象两种字段:仅当 ArtifactEngineRequest 定义了 model 字段、模型解析结果为 None 且 requires_model 为真时才抛 RsiNotReady("optimizer model 未注册");若请求只有 model_config 字段,则直接写入 model_id,即使 requires_model 为真也不校验是否解析到模型。代价是旧字段路径下未注册模型不会被提前拦截,收益是与上游字段演进保持边界兼容。 + +Sources / 来源:[jiuwenswarm/agents/harness/common/rsi/artifact_adapter.py:L355–L368](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/agents/harness/common/rsi/artifact_adapter.py#L355-L368) + diff --git a/knowledge/repos/jiuwenswarm/components/web-frontend/feature-share-image-export.md b/knowledge/repos/jiuwenswarm/components/web-frontend/feature-share-image-export.md index 3deab635..c40a3226 100644 --- a/knowledge/repos/jiuwenswarm/components/web-frontend/feature-share-image-export.md +++ b/knowledge/repos/jiuwenswarm/components/web-frontend/feature-share-image-export.md @@ -1,10 +1,10 @@ --- title: "会话分享图导出:任务注册表与无头渲染器" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/share_image_export.py:L69-L98, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/share_image_export.py:L29-L40, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/vite.config.ts:L626-L636, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/vite.config.ts:L585-L597, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/vite.config.ts:L625-L628, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/vite.config.ts:L733-L736, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/vite.config.ts:L746-L765, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/vite.config.ts:L626-L673, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/vite.config.ts:L679-L731, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/share_image_export.py:L250-L271, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/shareImageExport.tsx:L1466-L1500] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/share_image_export.py:L69-L98, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/share_image_export.py:L29-L40, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/vite.config.ts:L626-L636, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/vite.config.ts:L585-L597, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/vite.config.ts:L625-L628, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/vite.config.ts:L733-L736, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/vite.config.ts:L746-L765, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/vite.config.ts:L626-L673, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/vite.config.ts:L679-L731, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/share_image_export.py:L250-L271, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/shareImageExport.tsx:L1466-L1500, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/vite.config.ts:L546-L548, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/channels/web/test_share_image_export.py:L274-L282, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:tests/unit_tests/channels/web/test_share_image_export.py:L537-L555, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/share_image_export.py:L43-L52, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/share_image_export.py:L239-L241, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/share_image_export.py:L91-L93] feature: "share-image-export" entry_points: ["jiuwenswarm/channels/web/frontend/vite.config.ts", "jiuwenswarm/channels/web/share_image_export.py"] source_globs: ["jiuwenswarm/channels/web/frontend/vite.config.ts", "jiuwenswarm/channels/web/share_image_export.py", "jiuwenswarm/channels/web/frontend/src/features/shareImageExport.tsx", "jiuwenswarm/channels/web/frontend/src/features/shareImageArchive.ts", "jiuwenswarm/channels/web/frontend/src/features/shareImageExport.css", "jiuwenswarm/channels/web/app_web.py", "jiuwenswarm/channels/web/frontend/src/features/shareImageJob.ts", "jiuwenswarm/channels/web/frontend/src/features/shareImagePng.worker.ts", "jiuwenswarm/channels/web/frontend/src/features/shareImagePngEncoder.ts", "jiuwenswarm/channels/web/frontend/src/App.tsx", "jiuwenswarm/channels/web/frontend/src/main.tsx", "jiuwenswarm/channels/web/frontend/src/features/shareImageRaster.ts"] @@ -36,3 +36,19 @@ Sources / 来源:[jiuwenswarm/channels/web/frontend/vite.config.ts:L585–L597 Sources / 来源:[jiuwenswarm/channels/web/frontend/vite.config.ts:L626–L673](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/vite.config.ts#L626-L673), [jiuwenswarm/channels/web/frontend/vite.config.ts:L679–L731](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/vite.config.ts#L679-L731), [jiuwenswarm/channels/web/share_image_export.py:L250–L271](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/share_image_export.py#L250-L271), [jiuwenswarm/channels/web/frontend/src/features/shareImageExport.tsx:L1466–L1500](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/features/shareImageExport.tsx#L1466-L1500) + + +**同会话活动任务复用** + +创建任务时按 session 去重:dev 服务端 `findActiveShareImageJob` 只匹配 queued/running 状态的任务,命中时不再创建新任务,直接返回既有任务状态并附加 `reused: true`。Python 侧 `ShareImageExportManager.create_job` 同样复用活动任务(返回 `reused` 标志),任务结束后 `get_active_status` 返回 None(测试中验证了 completed 后的清空)。浏览器凭据注入是另一项特性:桌面模式下 `ShareImageRenderAuth` 携带的 cookie 会在打开 runner 页面前注入同一 loopback origin(httpOnly、sameSite=Lax,不出现在 URL 中),普通 web 模式不注入。 + +Sources / 来源:[jiuwenswarm/channels/web/frontend/vite.config.ts:L546–L548](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/vite.config.ts#L546-L548), [jiuwenswarm/channels/web/frontend/vite.config.ts:L625–L628](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/vite.config.ts#L625-L628), [tests/unit_tests/channels/web/test_share_image_export.py:L274–L282](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/channels/web/test_share_image_export.py#L274-L282), [tests/unit_tests/channels/web/test_share_image_export.py:L537–L555](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/tests/unit_tests/channels/web/test_share_image_export.py#L537-L555) + + + +**独立无头浏览器与凭据隔离的代价** + +渲染选择在专用无头 Playwright Chromium 中执行而非复用桌面 WebView:源码注释指出无头 BrowserContext 不共享桌面 WebView 的 Cookie,因此必须把当前实例的 desktop cookie 注入同一 loopback origin,否则 `/share-export-runner` 直接 403。作为配套约束,`ShareImageRenderAuth` 的 `cookie_value` 用 `field(repr=False)` 抑制 repr,文档说明该令牌绝不能进入任务状态、快照文件、错误串或日志。代价是浏览器可用性依赖配置(`chrome_path` 指向的文件不存在时抛 `configured_share_export_browser_not_found`),且每个任务都要冷启动一个浏览器进程。 + +Sources / 来源:[jiuwenswarm/channels/web/share_image_export.py:L43–L52](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/share_image_export.py#L43-L52), [jiuwenswarm/channels/web/share_image_export.py:L239–L241](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/share_image_export.py#L239-L241), [jiuwenswarm/channels/web/share_image_export.py:L91–L93](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/share_image_export.py#L91-L93) + diff --git a/knowledge/repos/jiuwenswarm/components/web-frontend/feature-web-asset-publish-flow.md b/knowledge/repos/jiuwenswarm/components/web-frontend/feature-web-asset-publish-flow.md index fce3dbb7..3d1fa5fa 100644 --- a/knowledge/repos/jiuwenswarm/components/web-frontend/feature-web-asset-publish-flow.md +++ b/knowledge/repos/jiuwenswarm/components/web-frontend/feature-web-asset-publish-flow.md @@ -1,10 +1,10 @@ --- title: "Web 资产发布流程(prepare/commit/轮询/提交锁)" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/hooks/useAssetPublish.ts:L87-L114, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/hooks/useAssetPublish.ts:L151-L173, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/hooks/useAssetPublish.ts:L238-L249, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/hooks/useAssetPublish.ts:L257-L285, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/types/assetPublish.ts:L1-L3, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/assetPublishState.ts:L7-L15, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/assetPublishEvents.ts:L1-L4, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/assetPublication.ts:L17-L20, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/hooks/useAssetPublish.ts:L145-L173, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/hooks/useAssetPublish.ts:L96-L114, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/hooks/useAssetPublish.ts:L67-L70, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/assetPublishState.ts:L23-L41, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/assetPublishState.ts:L47-L60, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/hooks/useAssetPublish.ts:L20-L33, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/hooks/useAssetPublish.ts:L90-L95, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/hooks/useAssetPublish.ts:L174-L188, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/hooks/useAssetPublish.ts:L261-L269] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/hooks/useAssetPublish.ts:L87-L114, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/hooks/useAssetPublish.ts:L151-L173, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/hooks/useAssetPublish.ts:L238-L249, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/hooks/useAssetPublish.ts:L257-L285, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/types/assetPublish.ts:L1-L3, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/assetPublishState.ts:L7-L15, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/assetPublishEvents.ts:L1-L4, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/assetPublication.ts:L17-L20, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/hooks/useAssetPublish.ts:L145-L173, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/hooks/useAssetPublish.ts:L96-L114, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/hooks/useAssetPublish.ts:L67-L70, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/assetPublishState.ts:L23-L41, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/assetPublishState.ts:L47-L60, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/hooks/useAssetPublish.ts:L20-L33, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/hooks/useAssetPublish.ts:L90-L95, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/hooks/useAssetPublish.ts:L174-L188, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/hooks/useAssetPublish.ts:L261-L269, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/features/assetPublishState.ts:L16-L22, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/hooks/useAssetPublish.ts:L212-L216] feature: "web-asset-publish-flow" entry_points: ["jiuwenswarm/channels/web/frontend/src/hooks/useAssetPublish.ts"] source_globs: ["jiuwenswarm/channels/web/frontend/src/hooks/useAssetPublish.ts", "jiuwenswarm/channels/web/frontend/src/types/assetPublish.ts", "jiuwenswarm/channels/web/frontend/src/features/assetPublication.ts", "jiuwenswarm/channels/web/frontend/src/features/assetPublishErrors.ts", "jiuwenswarm/channels/web/frontend/src/features/assetPublishEvents.ts", "jiuwenswarm/channels/web/frontend/src/features/assetPublishState.ts"] @@ -52,3 +52,11 @@ Sources / 来源:[jiuwenswarm/channels/web/frontend/src/features/assetPublishS Sources / 来源:[jiuwenswarm/channels/web/frontend/src/hooks/useAssetPublish.ts:L20–L33](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/hooks/useAssetPublish.ts#L20-L33), [jiuwenswarm/channels/web/frontend/src/hooks/useAssetPublish.ts:L90–L95](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/hooks/useAssetPublish.ts#L90-L95), [jiuwenswarm/channels/web/frontend/src/hooks/useAssetPublish.ts:L174–L188](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/hooks/useAssetPublish.ts#L174-L188), [jiuwenswarm/channels/web/frontend/src/hooks/useAssetPublish.ts:L261–L269](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/hooks/useAssetPublish.ts#L261-L269) + + +**验证入口:导出的元数据校验纯函数与 commit 前运行时守卫** + +展示的文件中不包含自动化测试;可指认的验证入口有两类。其一为源码级校验函数:`validateMetadata`(assetPublishState.ts)是导出的纯函数,对 `asset_name`(小写字母/数字/-/_ 正则)、`version`(三段数字或 7 位十六进制正则)与 `display_name`(非空且 ≤128 字符)做检查并返回违规字段名数组,展示范围内未出现调用它的代码。其二为 useAssetPublish 中 commit 的运行时守卫(非测试):busy、缺少 `draft_id`、`can_submit` 为假、`draft.errors` 非空或已存在 record 时直接拒绝提交;且仅当 `attempt.current` 尚未创建时才检查 `draft.expires_at`,已过期则设置 error 'expired' 并清空 draft。 + +Sources / 来源:[jiuwenswarm/channels/web/frontend/src/features/assetPublishState.ts:L16–L22](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/features/assetPublishState.ts#L16-L22), [jiuwenswarm/channels/web/frontend/src/hooks/useAssetPublish.ts:L212–L216](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/hooks/useAssetPublish.ts#L212-L216) + diff --git a/knowledge/repos/jiuwenswarm/components/web-frontend/feature-web-i18n-zh-en.md b/knowledge/repos/jiuwenswarm/components/web-frontend/feature-web-i18n-zh-en.md index 805d0bb6..62f851c4 100644 --- a/knowledge/repos/jiuwenswarm/components/web-frontend/feature-web-i18n-zh-en.md +++ b/knowledge/repos/jiuwenswarm/components/web-frontend/feature-web-i18n-zh-en.md @@ -1,10 +1,10 @@ --- title: "Web 前端中英双语 i18n 初始化(jiuwenswarm/channels/web/frontend)" created: 2026-10-06 -updated: 2026-10-06 +updated: 2026-10-07 type: architecture tags: [jiuwenswarm] -sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/i18n/index.ts:L1-L30, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/App.tsx:L2114-L2125, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/i18n/index.ts:L15-L28, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/i18n/index.ts:L1-L18, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/App.tsx:L1878-L1898, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/i18n/index.ts:L12-L30, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/i18n/index.ts:L17-L27] +sources: [openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/i18n/index.ts:L1-L30, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/App.tsx:L2114-L2125, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/i18n/index.ts:L15-L28, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/i18n/index.ts:L1-L18, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/App.tsx:L1878-L1898, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/i18n/index.ts:L12-L30, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/i18n/index.ts:L17-L27, openJiuwen-ai/jiuwenswarm@f0a69728c96b5961d993449f1a901cbd2f4dac5b:jiuwenswarm/channels/web/frontend/src/i18n/index.ts:L12-L28] feature: "web-i18n-zh-en" entry_points: ["jiuwenswarm/channels/web/frontend/src/i18n/index.ts"] source_globs: ["jiuwenswarm/channels/web/frontend/src/i18n/index.ts", "jiuwenswarm/channels/web/frontend/src/App.tsx"] @@ -52,3 +52,11 @@ Sources / 来源:[jiuwenswarm/channels/web/frontend/src/i18n/index.ts:L12–L3 Sources / 来源:[jiuwenswarm/channels/web/frontend/src/i18n/index.ts:L17–L27](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/i18n/index.ts#L17-L27), [jiuwenswarm/channels/web/frontend/src/App.tsx:L2114–L2125](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/App.tsx#L2114-L2125) + + +**语言同步的运行时防护(非自动化测试)** + +所示代码中该功能的健壮性保障是运行时防护而非测试:连接后同步 `locale.get_conf` 的 effect 只在后端 `preferred_language` 严格等于 `'zh'` 或 `'en'` 时才调用 `i18n.changeLanguage`,其余值被忽略;请求失败由空的 `.catch(() => {})` 静默吞掉,保证语言同步失败不阻塞连接后的主流程。所展示的文件片段中未包含针对 i18n 初始化或语言同步的自动化测试入口,此处仅描述运行时守卫,不构成测试执行证据。 + +Sources / 来源:[jiuwenswarm/channels/web/frontend/src/App.tsx:L2114–L2125](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/App.tsx#L2114-L2125), [jiuwenswarm/channels/web/frontend/src/i18n/index.ts:L12–L28](https://github.com/openJiuwen-ai/jiuwenswarm/blob/f0a69728c96b5961d993449f1a901cbd2f4dac5b/jiuwenswarm/channels/web/frontend/src/i18n/index.ts#L12-L28) + diff --git a/src/infermatrix_copilot/knowledge_service/pinned_claims.py b/src/infermatrix_copilot/knowledge_service/pinned_claims.py index 3ecc53c2..1f58903e 100644 --- a/src/infermatrix_copilot/knowledge_service/pinned_claims.py +++ b/src/infermatrix_copilot/knowledge_service/pinned_claims.py @@ -29,6 +29,7 @@ import json import re import subprocess +from threading import RLock from dataclasses import dataclass from pathlib import Path from typing import Callable, Iterable, Mapping @@ -64,6 +65,13 @@ def __init__(self, repo_dir: str | Path, repository: str, pin: str, *, self.pin = pin self._pull = pull or _gh_pull self._commits: set[str] = set() + # Successful immutable Git reads can be reused within this observer. + # A fresh observer starts empty; read failures and live PR metadata + # are never cached. Locking also avoids duplicate concurrent reads. + self._read_lock = RLock() + self._entries: dict[tuple[str, str], tuple[str, str] | None] = {} + self._texts: dict[tuple[str, str], str] = {} + self._top_levels: dict[str, frozenset[str]] = {} self._require_commit(pin) def _git(self, *args: str, input: bytes | None = None) -> subprocess.CompletedProcess: @@ -84,30 +92,52 @@ def _require_commit(self, sha: str) -> None: def head(self) -> str: return self.pin - def top_level(self, sha: str) -> set[str]: + def _immutable_commit(self, sha: str) -> str: + if not isinstance(sha, str) or not sha: + raise FactsError("a commit identity is required") + if not _SHA.fullmatch(sha): + proc = self._git("rev-parse", "--verify", "--end-of-options", sha) + resolved = proc.stdout.decode().strip() + if proc.returncode != 0 or not _SHA.fullmatch(resolved): + raise FactsError(f"cannot resolve commit {sha!r}: {proc.stderr.decode()[:300]}") + sha = resolved self._require_commit(sha) - proc = self._git("ls-tree", "--name-only", sha) - if proc.returncode != 0: - raise FactsError(f"cannot list {sha[:12]}: {proc.stderr.decode()[:300]}") - return {line for line in proc.stdout.decode("utf-8", "replace").splitlines() if line} + return sha + + def top_level(self, sha: str) -> set[str]: + with self._read_lock: + sha = self._immutable_commit(sha) + if sha not in self._top_levels: + proc = self._git("ls-tree", "--name-only", sha) + if proc.returncode != 0: + raise FactsError(f"cannot list {sha[:12]}: {proc.stderr.decode()[:300]}") + self._top_levels[sha] = frozenset(line for line in proc.stdout.decode("utf-8", "replace").splitlines() if line) + return set(self._top_levels[sha]) # callers cannot mutate the cache def _entry(self, sha: str, path: str) -> tuple[str, str] | None: """``(type, object id)`` of ``path`` in ``sha``'s tree; None when the tree has no such entry. Any git failure (unreadable tree, failed lazy fetch) raises: it is not evidence that the path is absent.""" - self._require_commit(sha) - path = path.strip("/") - if not path: - return None - proc = self._git("ls-tree", "-z", sha, "--", path) - if proc.returncode != 0: - raise FactsError(f"cannot list {path} at {sha[:12]}: {proc.stderr.decode()[:300]}") - for record in proc.stdout.decode("utf-8", "replace").split("\0"): - meta, _, name = record.partition("\t") - parts = meta.split() - if name == path and len(parts) == 3: - return parts[1], parts[2] - return None + with self._read_lock: + sha = self._immutable_commit(sha) + path = path.strip("/") + if not path: + return None + key = (sha, path) + if key in self._entries: + return self._entries[key] + proc = self._git("ls-tree", "-z", sha, "--", path) + if proc.returncode != 0: + raise FactsError(f"cannot list {path} at {sha[:12]}: {proc.stderr.decode()[:300]}") + for record in proc.stdout.decode("utf-8", "replace").split("\0"): + meta, _, name = record.partition("\t") + parts = meta.split() + if name == path and len(parts) == 3: + self._entries[key] = (parts[1], parts[2]) + return self._entries[key] + if not proc.stdout: + self._entries[key] = None # an empty successful lookup is immutable + return None # unexpected output is not cached def path_exists(self, sha: str, path: str) -> bool: return self._entry(sha, path) is not None @@ -115,13 +145,19 @@ def path_exists(self, sha: str, path: str) -> bool: def file_text(self, sha: str, path: str) -> str | None: """The file's text at ``sha``; None unless ``path`` is a file (blob). An entry that exists but cannot be read raises ``FactsError``.""" - entry = self._entry(sha, path) - if entry is None or entry[0] != "blob": - return None # missing, or a directory / submodule: no file text - proc = self._git("cat-file", "blob", entry[1]) - if proc.returncode != 0: - raise FactsError(f"cannot read {path} at {sha[:12]}: {proc.stderr.decode()[:300]}") - return proc.stdout.decode("utf-8", "replace") + with self._read_lock: + sha = self._immutable_commit(sha) + key = (sha, path) + if key in self._texts: + return self._texts[key] + entry = self._entry(sha, path) + if entry is None or entry[0] != "blob": + return None # missing, or a directory / submodule: no file text + proc = self._git("cat-file", "blob", entry[1]) + if proc.returncode != 0: + raise FactsError(f"cannot read {path} at {sha[:12]}: {proc.stderr.decode()[:300]}") + self._texts[key] = proc.stdout.decode("utf-8", "replace") + return self._texts[key] def pull(self, number: int) -> dict: """The PR as GitHub reports it. Every lookup failure (no ``gh``, a diff --git a/test/test_kb_pinned_observer_cache.py b/test/test_kb_pinned_observer_cache.py new file mode 100644 index 00000000..dded7811 --- /dev/null +++ b/test/test_kb_pinned_observer_cache.py @@ -0,0 +1,173 @@ +"""Successful immutable reads are reused without hiding read errors or live PR changes.""" +from __future__ import annotations + +from concurrent.futures import ThreadPoolExecutor +from pathlib import Path +import subprocess +import tempfile +from threading import Barrier +import unittest + +from infermatrix_copilot.knowledge_service.facts import FactsError +from infermatrix_copilot.knowledge_service.pinned_claims import PinnedObserver + + +class PinnedObserverCacheTests(unittest.TestCase): + def setUp(self): + self.scratch = tempfile.TemporaryDirectory(prefix="kb-observer-cache-test-") + self.addCleanup(self.scratch.cleanup) + self.root = Path(self.scratch.name) + self.git("init", "-q") + (self.root / "src").mkdir() + (self.root / "src/main.py").write_text("answer = 1\n") + self.git("add", ".") + self.git("-c", "user.name=KB Test", "-c", "user.email=kb-test@example.invalid", "commit", "-qm", "first") + self.old = self.git("rev-parse", "HEAD").decode().strip() + (self.root / "src/main.py").write_text("answer = 2\n") + (self.root / "new-component").mkdir() + (self.root / "new-component/entry.py").write_text("ready = True\n") + self.git("add", ".") + self.git("-c", "user.name=KB Test", "-c", "user.email=kb-test@example.invalid", "commit", "-qm", "second") + self.new = self.git("rev-parse", "HEAD").decode().strip() + self.observer = PinnedObserver(self.root, "example/repo", self.new) + self.calls = [] + original = self.observer._git + def counting(*args, **kwargs): + self.calls.append(args) + return original(*args, **kwargs) + self.observer._git = counting + + def git(self, *args): + return subprocess.check_output(["git", "-C", str(self.root), *args], stderr=subprocess.PIPE) + + def fail_once(self, predicate): + original = self.observer._git + failed = False + def flaky(*args, **kwargs): + nonlocal failed + if predicate(args) and not failed: + failed = True + self.calls.append(args) + return subprocess.CompletedProcess(args, 128, b"", b"injected read failure") + return original(*args, **kwargs) + self.observer._git = flaky + + def test_success_reuse_is_bound_to_commit_and_does_not_change_with_head(self): + self.assertEqual(self.observer.file_text(self.old, "src/main.py"), "answer = 1\n") + self.assertEqual(self.observer.file_text(self.new, "src/main.py"), "answer = 2\n") + before = len(self.calls) + for _ in range(100): + self.assertEqual(self.observer.file_text(self.old, "src/main.py"), "answer = 1\n") + self.assertEqual(self.observer.file_text(self.new, "src/main.py"), "answer = 2\n") + self.assertTrue(self.observer.path_exists(self.old, "src/main.py")) + self.assertEqual(len(self.calls), before) + (self.root / "src/main.py").write_text("uncommitted change\n") + self.assertEqual(self.observer.file_text(self.old, "src/main.py"), "answer = 1\n") + self.assertEqual(self.observer.file_text(self.new, "src/main.py"), "answer = 2\n") + + def test_top_level_is_bound_to_commit_and_returned_sets_cannot_poison_cache(self): + old = self.observer.top_level(self.old) + self.assertEqual(old, {"src"}) + old.add("invented") + self.assertEqual(self.observer.top_level(self.old), {"src"}) + self.assertEqual(self.observer.top_level(self.new), {"src", "new-component"}) + before = len(self.calls) + self.observer.top_level(self.new).clear() + self.assertEqual(self.observer.top_level(self.new), {"src", "new-component"}) + self.assertEqual(len(self.calls), before) + + def test_moving_head_and_branch_are_resolved_before_cache_reuse(self): + self.git("checkout", "-q", "--detach", self.old) + self.assertEqual(self.observer.file_text("HEAD", "src/main.py"), "answer = 1\n") + self.assertEqual(self.observer.top_level("HEAD"), {"src"}) + self.assertFalse(self.observer.path_exists("HEAD", "new-component/entry.py")) + self.git("checkout", "-q", "--detach", self.new) + self.assertEqual(self.observer.file_text("HEAD", "src/main.py"), "answer = 2\n") + self.assertEqual(self.observer.top_level("HEAD"), {"src", "new-component"}) + self.assertTrue(self.observer.path_exists("HEAD", "new-component/entry.py")) + self.git("update-ref", "refs/heads/probe", self.old) + self.assertEqual(self.observer.file_text("probe", "src/main.py"), "answer = 1\n") + self.git("update-ref", "refs/heads/probe", self.new) + self.assertEqual(self.observer.file_text("probe", "src/main.py"), "answer = 2\n") + self.assertEqual(self.observer.head(), self.new) + + def test_only_a_successful_empty_lookup_can_reuse_known_missing_entry(self): + self.assertIsNone(self.observer.file_text(self.new, "missing.py")) + before = len(self.calls) + self.assertFalse(self.observer.path_exists(self.new, "missing.py")) + self.assertIsNone(self.observer.file_text(self.new, "missing.py")) + self.assertEqual(len(self.calls), before) + self.assertIsNone(self.observer.file_text(self.new, "src")) + self.assertTrue(self.observer.path_exists(self.new, "src")) + + def test_entry_read_failure_remains_unknown_and_is_retried(self): + self.fail_once(lambda args: args[:2] == ("ls-tree", "-z")) + with self.assertRaises(FactsError): + self.observer.file_text(self.new, "src/main.py") + self.assertEqual(self.observer.file_text(self.new, "src/main.py"), "answer = 2\n") + self.assertEqual(sum(args[:2] == ("ls-tree", "-z") for args in self.calls), 2) + + def test_blob_read_failure_remains_unknown_and_is_retried(self): + self.fail_once(lambda args: args[:2] == ("cat-file", "blob")) + with self.assertRaises(FactsError): + self.observer.file_text(self.new, "src/main.py") + self.assertEqual(self.observer.file_text(self.new, "src/main.py"), "answer = 2\n") + before = len(self.calls) + self.assertEqual(self.observer.file_text(self.new, "src/main.py"), "answer = 2\n") + self.assertEqual(len(self.calls), before) + self.assertEqual(sum(args[:2] == ("cat-file", "blob") for args in self.calls), 2) + + def test_top_level_failure_is_not_cached_as_empty(self): + self.fail_once(lambda args: args[:2] == ("ls-tree", "--name-only")) + with self.assertRaises(FactsError): + self.observer.top_level(self.new) + self.assertEqual(self.observer.top_level(self.new), {"src", "new-component"}) + self.assertEqual(sum(args[:2] == ("ls-tree", "--name-only") for args in self.calls), 2) + + def test_unexpected_lookup_output_is_not_cached_as_verified_missing(self): + original = self.observer._git + unexpected = True + def broken(*args, **kwargs): + if args[:2] == ("ls-tree", "-z") and unexpected: + self.calls.append(args) + return subprocess.CompletedProcess(args, 0, b"unparsed-output\0", b"") + return original(*args, **kwargs) + self.observer._git = broken + self.assertIsNone(self.observer.file_text(self.new, "src/main.py")) + self.assertIsNone(self.observer.file_text(self.new, "src/main.py")) + self.assertEqual(sum(args[:2] == ("ls-tree", "-z") for args in self.calls), 2) + unexpected = False + self.assertEqual(self.observer.file_text(self.new, "src/main.py"), "answer = 2\n") + + def test_fresh_observer_rechecks_source_and_detects_new_read_failure(self): + self.observer.file_text(self.new, "src/main.py") + fresh = PinnedObserver(self.root, "example/repo", self.new) + def unreadable(*args, **kwargs): + return subprocess.CompletedProcess(args, 128, b"", b"injected read failure") + fresh._git = unreadable + with self.assertRaises(FactsError): + fresh.file_text(self.new, "src/main.py") + + def test_thirteen_threads_share_one_successful_source_read(self): + barrier = Barrier(13) + def read(_): + barrier.wait() + return self.observer.file_text(self.new, "src/main.py") + with ThreadPoolExecutor(max_workers=13) as pool: + self.assertEqual(list(pool.map(read, range(13))), ["answer = 2\n"] * 13) + self.assertEqual(sum(args[:2] == ("ls-tree", "-z") for args in self.calls), 1) + self.assertEqual(sum(args[:2] == ("cat-file", "blob") for args in self.calls), 1) + + def test_live_pull_metadata_is_never_cached(self): + calls = [] + def pull(repo, number): + calls.append((repo, number)) + return {"number": number, "revision": len(calls)} + observer = PinnedObserver(self.root, "example/repo", self.new, pull=pull) + self.assertEqual(observer.pull(7)["revision"], 1) + self.assertEqual(observer.pull(7)["revision"], 2) + self.assertEqual(calls, [("example/repo", 7)] * 2) + + +if __name__ == "__main__": + unittest.main() From bb74e1e4a4bff2f92902283e2831ef20c10e7132 Mon Sep 17 00:00:00 2001 From: tzhouam Date: Wed, 7 Oct 2026 19:50:29 +0800 Subject: [PATCH 5/5] Record final knowledge validation and sync pinned observer spec --- .../SPEC/knowledge_service/pinned_claims.md | 11 +- .../jiuwenswarm-init-completion-20261007.json | 113 +++++++++++++++++- .../jiuwenswarm-init-completion-20261007.md | 9 +- 3 files changed, 125 insertions(+), 8 deletions(-) diff --git a/doc/architecture/SPEC/knowledge_service/pinned_claims.md b/doc/architecture/SPEC/knowledge_service/pinned_claims.md index 757d5539..fba2ae29 100644 --- a/doc/architecture/SPEC/knowledge_service/pinned_claims.md +++ b/doc/architecture/SPEC/knowledge_service/pinned_claims.md @@ -1,8 +1,8 @@ # knowledge_service/pinned_claims.py —— 规范 - + -`LOC ~200 · 在钉住的上游 SHA 上核验规则声明与代码证据(kb init §9.1) · refactor-status: new` +`LOC ~280 · 在钉住的上游 SHA 上核验规则声明与代码证据(kb init §9.1) · refactor-status: new` ## 职责 - `PinnedObserver(repo_dir, repository, pin, pull=)`:在本地 git 仓库(bare 或非 bare)上实现 @@ -21,6 +21,11 @@ 哈希口径:`str.splitlines()` 切行(`\n`、`\r\n`、缺末尾换行视为相同),取 `start..end` 行以 `\n` 连接再补一个 `\n`,UTF-8 编码后 SHA-256。`Evidence.to_dict()/from_dict()` 用于 init 记录。 +同一 observer 复用成功的树项、文件正文和顶层目录读取,缓存键绑定完整提交 SHA 与路径。 +`HEAD`、分支等可变引用每次先解析为完整提交,再选缓存键;新 observer 从空缓存开始。 +成功的空树项查询可以缓存,读取失败不缓存;实时 PR 元数据仍逐次查询。 +并发读取使用实例锁,顶层目录集合返回副本,不允许调用方改写缓存。缓存不改变证据正文或哈希口径。 + ## 不变量 - 与服务端 `facts.attest` 的声明抽取完全一致(同一 `claims_in`),只是观测点从上游 head 换成钉点。 - 不修改 `facts.Observer` 协议,不影响服务与发布器。 @@ -35,3 +40,5 @@ ## 测试 `test_kb_pinned_claims.py`(临时 git 仓库:钉点前后文件、符号、PR 合并先后与未合并、证据区间与 哈希、换行风格无关、非法钉点)。 +`test_kb_pinned_observer_cache.py`(真实 Git 对象的重复读取、不同提交、并发复用、错误恢复、 +返回集合隔离、实时 PR 查询及移动 HEAD/分支的回归检查)。 diff --git a/eval/knowledge-depth/jiuwenswarm-init-completion-20261007.json b/eval/knowledge-depth/jiuwenswarm-init-completion-20261007.json index f78922e9..907cecbb 100644 --- a/eval/knowledge-depth/jiuwenswarm-init-completion-20261007.json +++ b/eval/knowledge-depth/jiuwenswarm-init-completion-20261007.json @@ -15,6 +15,11 @@ } }, "artifacts": { + "completed_legacy_serving_probes": { + "bytes": 3025237, + "path": ".kb-jiuwenswarm-finish-20261007/final-audit/serving-final/legacy-all-features.json", + "sha256": "3e1e03224894d85438bfdb3284d983fbf5285dd5cbef1e724f5f782457fc3c18" + }, "depth_archive_with_zero_task_declarations": { "bytes": 2994812, "path": ".kb-jiuwenswarm-finish-20261007/final-audit/depth-native-archive-manifest.json", @@ -25,6 +30,16 @@ "path": ".kb-jiuwenswarm-finish-20261007/final-audit/native-approvals-1178.json", "sha256": "13548385cecd19fe76e37155ac864ada93bb22bf4cbcda17f89feba691bb2ad1" }, + "final_frozen_full_suite_log": { + "bytes": 5108, + "path": ".kb-jiuwenswarm-finish-20261007/audit/full-pytest-final-frozen.log", + "sha256": "7b3d8e41824cdfd955388570f27c7bc92787f32b2fa3f546a44f31340f55b9f7" + }, + "final_serving_acceptance_reconciliation": { + "bytes": 138251, + "path": ".kb-jiuwenswarm-finish-20261007/final-audit/serving-final/summary-reconciled.json", + "sha256": "c5902c243b171d05de4332a691b804a562f15f87aeaf43ef167e2aa8fd23a8ab" + }, "foundation_last_attempt_unknowns": { "bytes": 139540, "path": ".kb-jiuwenswarm-finish-20261007/foundation/foundation-unknown-33-20261007-v3.json", @@ -76,7 +91,7 @@ }, "catalog_features": 173, "catalog_sha256": "e6c37a346cccdaff5404c26a21b5a88f733150b1e0835c4a533a332d20df68ed", - "created_at": "2026-10-07T11:27:54.963822+00:00", + "created_at": "2026-10-07T11:46:27.074615+00:00", "current": { "all_seven_complete_features": 143, "depth": { @@ -318,11 +333,27 @@ } }, "fresh_pr_review_experiments": 0, - "knowledge_checkout_base_sha": "2d54c48fe31f83df298dec94a26e8fea30d8c95d", + "knowledge_checkout_base_sha": "465f3515ca350e4c5926240f0e405294c6d0913b", "knowledge_target_met": true, "knowledge_tool_validation": { - "CI": "see_pull_request", - "final_full_suite": "frozen_candidate_rerun_pending_at_report", + "CI": { + "claim_passed_at_report": false, + "status_reference": "pull_request_checks", + "url": "https://github.com/JiusiServe/InferMatrixCopilot/pull/327" + }, + "final_full_suite": { + "knowledge_tree_frozen": true, + "log": { + "bytes": 5108, + "path": ".kb-jiuwenswarm-finish-20261007/audit/full-pytest-final-frozen.log", + "sha256": "7b3d8e41824cdfd955388570f27c7bc92787f32b2fa3f546a44f31340f55b9f7" + }, + "passed": 3935, + "seconds": 941.09, + "skipped": 18, + "status": "passed", + "warnings": 4 + }, "fresh_SDK_related_rerun": { "passed": 35 }, @@ -497,10 +528,84 @@ } }, "previous_catalog_features": 79, + "pull_request": { + "number": 327, + "url": "https://github.com/JiusiServe/InferMatrixCopilot/pull/327" + }, "release_note": "本报告核对已审计候选;知识工具测试、CI及合并状态以本次PR记录为准。", "runtime_tests_executed": false, "schema": "jiuwenswarm-init-completion-public-v1", "scope_interpretation": "声明范围已处理不等于所有功能均已发现。原79项功能552/553;本轮固定173项,使用1211分母。", + "serving_acceptance": { + "SDK_MCP_parity_scenarios": 5, + "actual_packet_count": 15, + "code_binding_files": 287, + "code_bindings_sha256": "0edd0fa124f422d6dd3eb6c5c06d1f653e704c6b9297ade267733a7d9d4429c3", + "consumer_budget_checks": { + "assertion_origin": "Already executed by original helper before its line235 final assertion; successful packets/expansion reconstructed and verified separately.", + "direct_related_mcp_expand": true, + "initial_budget": 24000, + "max_budget": 64000, + "mcp_read_sdk_restart": true, + "path_boundary_enforced": true, + "sdk_search_mcp_cached_search": true, + "source_output_reserves_enforced": true + }, + "document_deliveries_including_repeats": 73, + "formal_changes": 0, + "ignored_nonserved_cache_additions": 4, + "intact_facet_deliveries_including_repeats": 151, + "interpretation": "依据已执行调用的持久化回执、注入内容哈希和忽略规则作确定性核对;不是把原始exit1改成exit0。保守UTF8预算记账不是服务端实测tokens。", + "legacy_cases": 519, + "legacy_probes": { + "description_and_paths": { + "cases": 173, + "depth_hits": 173, + "feature_hits": 173, + "max_content_chars": 5991, + "max_documents": 2, + "target_feature_injection": { + "full": 585, + "not_injected": 626, + "partial": 0 + } + }, + "paths_only": { + "cases": 173, + "depth_hits": 168, + "feature_hits": 168, + "max_content_chars": 5991, + "max_documents": 2, + "target_feature_injection": { + "full": 569, + "not_injected": 642, + "partial": 0 + } + }, + "query_only": { + "cases": 173, + "depth_hits": 173, + "feature_hits": 173, + "max_content_chars": 5873, + "max_documents": 2, + "target_feature_injection": { + "full": 614, + "not_injected": 597, + "partial": 0 + } + } + }, + "new_model_or_MCP_calls_in_reconciliation": 0, + "not_model_or_PR_review_latency": true, + "original_failure_preserved": true, + "original_helper_exit_code": 1, + "paths_only_miss_interpretation": "共享入口和两页预算造成诊断性缺口;不是PR评审召回率。", + "paths_only_misses": 5, + "persistent_context_receipts_verified": 32, + "rerun_legacy_probes": 0, + "status": "passed_after_nonserved_cache_reconciliation", + "workload_seconds_until_legacy_report": 1571.55 + }, "shared_inventory_unknowns": { "binary_text_read_failures": 4, "counted_as_absence": false, diff --git a/eval/knowledge-depth/jiuwenswarm-init-completion-20261007.md b/eval/knowledge-depth/jiuwenswarm-init-completion-20261007.md index a9984c4d..7350a0c8 100644 --- a/eval/knowledge-depth/jiuwenswarm-init-completion-20261007.md +++ b/eval/knowledge-depth/jiuwenswarm-init-completion-20261007.md @@ -2,7 +2,7 @@ **本轮已达到知识验收门槛:173个正式功能全部具备认可深度,七个维度分别超过90%,生产文件结构覆盖93.59%。** 基础说明从927项增至1005项,七维深度从已发布的552项增至1178项。仍有33项基础未知、33项深度未知,真实缺口继续保留。达到门槛不代表所有缺口已补齐。 -源码固定于 `f0a69728c96b5961d993449f1a901cbd2f4dac5b`,目录固定为173项;源码审计时间 `2026-10-07T11:09:53.113528+00:00`,报告生成时间 `2026-10-07T11:27:54.963822+00:00`。核查时develop仍与该源码一致,提交差距为0;核查时间 `2026-10-07T11:14:38.351141+00:00`。这次一致性不能描述为持续实时同步。最终工具测试、CI及合并状态以本次PR记录为准。 +源码固定于 `f0a69728c96b5961d993449f1a901cbd2f4dac5b`,目录固定为173项;源码审计时间 `2026-10-07T11:09:53.113528+00:00`,报告生成时间 `2026-10-07T11:46:27.074615+00:00`。核查时develop仍与该源码一致,提交差距为0;核查时间 `2026-10-07T11:14:38.351141+00:00`。这次一致性不能描述为持续实时同步。冻结知识树后的完整测试已通过;CI及合并状态参见 [PR #327](https://github.com/JiusiServe/InferMatrixCopilot/pull/327)。 功能从79扩至173后,分母从553扩大为1,211。原79功能曾达到552/553(99.82%);将相同内容放到本轮173功能目录中,才是552/1,211(45.58%)。这是范围扩大造成的统计变化。声明范围已经处理,也不代表所有潜在功能均已发现。 @@ -53,7 +53,9 @@ 基础与深度阶段并行,时间不能直接相加。共用并发上限13及Zcode排期。基础确定性审计实际读取源码374次,复用已成功读取内容9849次;这说明本地读取复用,不能据此计算GLM评审速度收益。最终代码的本地源码证据复放微基准使用20个真实路径、每路径10次读取、两组各3次平衡顺序运行;完整返回哈希一致,Git子进程每轮由401次降为41次,中位耗时7.002秒降为0.722秒(下降89.69%,约9.70倍)。这是本地读取基准,零模型调用,不能当作PR评审提速。补查实际32次模型调用为16次GLM‑5.3、16次Codex;GLM实际服务模型已报告为GLM‑5.3,Codex服务端未报告实际模型身份。费用仍未知。 -知识工具的140项整合测试、6项补查测试、26项固定源码缓存测试,以及安装后的SDK冒烟检查已通过;这些检查范围有重叠,不相加成测试总数。首次完整测试在基础知识组装期间运行,出现6处资源版本变化拒绝(3929通过、18跳过),失败记录已保留。冻结最终知识后,35项SDK相关复跑通过,完整套件正在重新运行;最终结果及CI以PR记录为准。没有为使测试通过而放宽资源版本校验。 +知识工具的140项整合测试、6项补查测试、26项固定源码缓存测试,以及安装后的SDK冒烟检查已通过;这些检查范围有重叠,不相加成测试总数。首次完整测试在基础知识组装期间运行,出现6处资源版本变化拒绝(3929通过、18跳过),失败记录已保留。冻结最终知识后,35项SDK相关复跑通过,完整套件复跑结果为3935通过、18跳过、4条警告,用时941.09秒。CI及合并状态参见 [PR #327](https://github.com/JiusiServe/InferMatrixCopilot/pull/327)。没有为使测试通过而放宽资源版本校验。 + +检索与服务验收已通过确定性归档核对。519次既有检索模式探针无记录问题:功能描述+路径、仅查询均命中173/173;仅路径命中168/173,剩余5项属于共享入口与两页预算的诊断性歧义,继续保留,不能称为PR缺陷召回率。既有模式实际最多2页、5991字符。另核对5组SDK/MCP一致性场景、跨消费者共享账本、24k起始及64k累计预算、源码与回答预留空间和路径边界;预算使用保守UTF8记账,不是模型服务端实测tokens。核对32条持久化回执、15个实际注入包,合计73次文档交付、151次完整维度交付(包含重复)。原始辅助进程exit1已保留:仅新增4个Git忽略且不服务的编译缓存,没有正式知识变化;依据实际回执与内容哈希完成核对,没有重跑519次探针或新增模型/MCP调用,也没有伪造原始exit0。287项代码/配置/验收工具哈希绑定未变。1571.55秒为离线验收任务耗时,不是PR或模型评审延迟。 这轮没有开展新的PR A/B评审实验。上下文增加可帮助评审定位入口、契约、配置和已知验证范围,但不能直接推导准确率、召回率或评审速度提升。例如,电话工具相关PR可以获得开关与装配断言;时间转换PR仍需要直接阅读转换实现及运行相应测试。模型只接收检索真正注入的内容,知识库总量不等于它收到的上下文。 @@ -68,6 +70,9 @@ | `.kb-jiuwenswarm-finish-20261007/final-audit/final-acceptance/candidate-files-manifest.json` | `ff959e125a84271cf9513a9a9d327086dd8f22b7ba3d7c2a67e91070f502704c` | | `.kb-jiuwenswarm-finish-20261007/final-audit/depth-native-archive-manifest.json` | `bad89a62a30fc5de4b1a7fb944269f17f39a8df3578647d3eaaef86f7a577763` | | `.kb-jiuwenswarm-finish-20261007/foundation/cache-proposal/local-replay-benchmark-final-candidate.json` | `b245b55933e18db907162b984a626749ed714f535433fcfa13ef117c064fc861` | +| `.kb-jiuwenswarm-finish-20261007/audit/full-pytest-final-frozen.log` | `7b3d8e41824cdfd955388570f27c7bc92787f32b2fa3f546a44f31340f55b9f7` | +| `.kb-jiuwenswarm-finish-20261007/final-audit/serving-final/legacy-all-features.json` | `3e1e03224894d85438bfdb3284d983fbf5285dd5cbef1e724f5f782457fc3c18` | +| `.kb-jiuwenswarm-finish-20261007/final-audit/serving-final/summary-reconciled.json` | `c5902c243b171d05de4332a691b804a562f15f87aeaf43ef167e2aa8fd23a8ab` | | `.kb-jiuwenswarm-finish-20261007/final-audit/final-acceptance/native-archive-manifest.json` | `ff3efc1878589e9ace5d656e5847d66f5bfd2207f02af235e29f830d821b4a19` | 剩余深度未知如下。完整基础/深度逐项原因与原生追踪标识见同名紧凑JSON;这些项目未被伪装成已核实缺失。