qwen-sci 0.2.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- qwen_sci-0.2.2.dist-info/METADATA +492 -0
- qwen_sci-0.2.2.dist-info/RECORD +549 -0
- qwen_sci-0.2.2.dist-info/WHEEL +4 -0
- qwen_sci-0.2.2.dist-info/entry_points.txt +6 -0
- qwen_sci-0.2.2.dist-info/licenses/LICENSE +21 -0
- src/1.txt +1 -0
- src/__init__.py +1 -0
- src/__main__.py +5 -0
- src/agents/__init__.py +1 -0
- src/agents/experiment_design_agent/__init__.py +268 -0
- src/agents/experiment_design_agent/artifacts.py +747 -0
- src/agents/experiment_design_agent/cache.py +319 -0
- src/agents/experiment_design_agent/completeness.py +130 -0
- src/agents/experiment_design_agent/contracts.py +771 -0
- src/agents/experiment_design_agent/counterexample_analyzer.py +187 -0
- src/agents/experiment_design_agent/design_evidence_paper_screener.py +470 -0
- src/agents/experiment_design_agent/discipline_catalog.py +178 -0
- src/agents/experiment_design_agent/evidence_cards.py +338 -0
- src/agents/experiment_design_agent/evidence_planner.py +452 -0
- src/agents/experiment_design_agent/formal_reasoning_planner.py +884 -0
- src/agents/experiment_design_agent/fulltext_acquisition.py +863 -0
- src/agents/experiment_design_agent/idea_adapter.py +100 -0
- src/agents/experiment_design_agent/idea_intake.py +87 -0
- src/agents/experiment_design_agent/llm_json.py +328 -0
- src/agents/experiment_design_agent/orchestrator.py +1220 -0
- src/agents/experiment_design_agent/reasoning_context.py +183 -0
- src/agents/experiment_design_agent/reasoning_validation.py +546 -0
- src/agents/experiment_design_agent/run.py +481 -0
- src/agents/experiment_design_agent/run_logging.py +292 -0
- src/agents/experiment_design_agent/scope_gate.py +198 -0
- src/agents/experiment_design_agent/study_type_composer.py +1360 -0
- src/agents/experiment_design_agent/survey_evidence.py +1381 -0
- src/agents/experiment_design_agent/template_router.py +195 -0
- src/agents/experiment_design_agent/variable_claim_extractor.py +93 -0
- src/agents/idea_agent/__init__.py +1 -0
- src/agents/idea_agent/agent/__init__.py +6 -0
- src/agents/idea_agent/agent/artifacts.py +308 -0
- src/agents/idea_agent/agent/base.py +122 -0
- src/agents/idea_agent/agent/ligagent.py +488 -0
- src/agents/idea_agent/agent/mcts.py +2060 -0
- src/agents/idea_agent/agent/prompts/__init__.py +48 -0
- src/agents/idea_agent/agent/prompts/advanced_analysis.py +235 -0
- src/agents/idea_agent/agent/prompts/algorithm_alignment.py +55 -0
- src/agents/idea_agent/agent/prompts/algorithm_structuring.py +48 -0
- src/agents/idea_agent/agent/prompts/component_extraction.py +62 -0
- src/agents/idea_agent/agent/prompts/component_novelty_evaluation.py +54 -0
- src/agents/idea_agent/agent/prompts/experiment_findings_extraction.py +39 -0
- src/agents/idea_agent/agent/prompts/idea_fusion.py +295 -0
- src/agents/idea_agent/agent/prompts/idea_introduction.py +30 -0
- src/agents/idea_agent/agent/prompts/idea_result_alignment.py +39 -0
- src/agents/idea_agent/agent/prompts/input_interpreter.py +52 -0
- src/agents/idea_agent/agent/prompts/keynote_ops.py +78 -0
- src/agents/idea_agent/agent/prompts/mcts_evaluation.py +235 -0
- src/agents/idea_agent/agent/prompts/mcts_generation.py +140 -0
- src/agents/idea_agent/agent/prompts/mechanism_commit_query.py +99 -0
- src/agents/idea_agent/agent/prompts/memory_selection.py +0 -0
- src/agents/idea_agent/agent/prompts/prompt_modes.py +16 -0
- src/agents/idea_agent/agent/prompts/rag_query.py +34 -0
- src/agents/idea_agent/agent/prompts/re_analysis_replan.py +48 -0
- src/agents/idea_agent/agent/prompts/reference_grounding.py +34 -0
- src/agents/idea_agent/agent/prompts/root_domain_classification.py +32 -0
- src/agents/idea_agent/agent/prompts/scientific_debate.py +88 -0
- src/agents/idea_agent/agent/prompts/scientific_materialization.py +45 -0
- src/agents/idea_agent/agent/prompts/skill_instantiation.py +193 -0
- src/agents/idea_agent/agent/prompts/theory_transfer_query.py +93 -0
- src/agents/idea_agent/agent/prompts/topic_background.py +15 -0
- src/agents/idea_agent/agent/skills/DEFAULT_SKILL_TEMPLATES.json +263 -0
- src/agents/idea_agent/agent/skills/edit_operator_skills/alternative-path-contrast/SKILL.md +40 -0
- src/agents/idea_agent/agent/skills/edit_operator_skills/alternative-path-contrast/references/contrast_patterns.md +22 -0
- src/agents/idea_agent/agent/skills/edit_operator_skills/feedback-closed-loop/SKILL.md +40 -0
- src/agents/idea_agent/agent/skills/edit_operator_skills/feedback-closed-loop/references/mechanism_cards.md +24 -0
- src/agents/idea_agent/agent/skills/edit_operator_skills/hierarchical-decomposition/SKILL.md +39 -0
- src/agents/idea_agent/agent/skills/edit_operator_skills/hierarchical-decomposition/references/hierarchy_patterns.md +22 -0
- src/agents/idea_agent/agent/skills/edit_operator_skills/mechanism-commit-innovation/SKILL.md +39 -0
- src/agents/idea_agent/agent/skills/edit_operator_skills/mechanism-commit-innovation/references/mechanism_commit_patterns.md +24 -0
- src/agents/idea_agent/agent/skills/edit_operator_skills/multi-scale-coordinator/SKILL.md +39 -0
- src/agents/idea_agent/agent/skills/edit_operator_skills/multi-scale-coordinator/references/coordination_patterns.md +22 -0
- src/agents/idea_agent/agent/skills/edit_operator_skills/speculative-execution-with-repair/SKILL.md +41 -0
- src/agents/idea_agent/agent/skills/edit_operator_skills/speculative-execution-with-repair/references/speculation_patterns.md +22 -0
- src/agents/idea_agent/agent/skills/edit_operator_skills/surgical-modularity/SKILL.md +39 -0
- src/agents/idea_agent/agent/skills/edit_operator_skills/surgical-modularity/references/modularity_patterns.md +22 -0
- src/agents/idea_agent/agent/skills/edit_operator_skills/theory-transfer-injection/SKILL.md +40 -0
- src/agents/idea_agent/agent/skills/edit_operator_skills/theory-transfer-injection/references/transfer_patterns.md +24 -0
- src/agents/idea_agent/example/idea_result.json +900 -0
- src/agents/idea_agent/run.py +276 -0
- src/agents/idea_agent/tests/test_advanced_analysis_contract.py +90 -0
- src/agents/idea_agent/tests/test_gap_hypothesis_bridge.py +166 -0
- src/agents/idea_agent/tests/test_idea_debate.py +480 -0
- src/agents/idea_agent/tests/test_idea_result_v5.py +99 -0
- src/agents/idea_agent/tests/test_idea_synthesis.py +92 -0
- src/agents/idea_agent/tests/test_mature_idea_sources.py +27 -0
- src/agents/idea_agent/tests/test_multimodal_idea_integration.py +386 -0
- src/agents/idea_agent/tests/test_profile_materialization_and_scoring.py +219 -0
- src/agents/idea_agent/tests/test_profile_native_skill_rendering.py +122 -0
- src/agents/idea_agent/tests/test_result_persistence.py +183 -0
- src/agents/idea_agent/tests/test_scientific_intervention_profiles.py +241 -0
- src/agents/idea_agent/tests/test_scientific_rubric_and_prompts.py +559 -0
- src/agents/idea_agent/tests/test_strict_json_object_responses.py +48 -0
- src/agents/idea_agent/utils/core/__init__.py +1 -0
- src/agents/idea_agent/utils/core/ablation_inputs.py +60 -0
- src/agents/idea_agent/utils/core/chat_errors.py +95 -0
- src/agents/idea_agent/utils/core/chat_router.py +130 -0
- src/agents/idea_agent/utils/core/chat_transport.py +188 -0
- src/agents/idea_agent/utils/core/config_loader.py +166 -0
- src/agents/idea_agent/utils/core/json_utils.py +28 -0
- src/agents/idea_agent/utils/core/logger.py +287 -0
- src/agents/idea_agent/utils/core/progress.py +58 -0
- src/agents/idea_agent/utils/core/response_parsing.py +57 -0
- src/agents/idea_agent/utils/core/run_inputs.py +198 -0
- src/agents/idea_agent/utils/mcts/__init__.py +1 -0
- src/agents/idea_agent/utils/mcts/component_novelty.py +342 -0
- src/agents/idea_agent/utils/mcts/defect_registry.py +302 -0
- src/agents/idea_agent/utils/mcts/idea_routes.py +61 -0
- src/agents/idea_agent/utils/mcts/idea_taste_presets.py +312 -0
- src/agents/idea_agent/utils/mcts/mcts_helpers.py +738 -0
- src/agents/idea_agent/utils/mcts/mcts_runtime.py +3000 -0
- src/agents/idea_agent/utils/mcts/scientific_intervention_ontology.py +1561 -0
- src/agents/idea_agent/utils/mcts/scientific_rubric.py +211 -0
- src/agents/idea_agent/utils/mcts/skill_parsing.py +92 -0
- src/agents/idea_agent/utils/papers/__init__.py +1 -0
- src/agents/idea_agent/utils/papers/paper_graph_vector_store.py +499 -0
- src/agents/idea_agent/utils/papers/paper_repository.py +372 -0
- src/agents/idea_agent/utils/prompting/__init__.py +1 -0
- src/agents/idea_agent/utils/prompting/prompt_views.py +637 -0
- src/agents/idea_agent/utils/workflow/__init__.py +1 -0
- src/agents/idea_agent/utils/workflow/advanced_analysis_contract.py +244 -0
- src/agents/idea_agent/utils/workflow/gap_hypothesis_bridge.py +461 -0
- src/agents/idea_agent/utils/workflow/idea_contract.py +426 -0
- src/agents/idea_agent/utils/workflow/idea_debate.py +1238 -0
- src/agents/idea_agent/utils/workflow/idea_diversity.py +163 -0
- src/agents/idea_agent/utils/workflow/idea_fusion.py +889 -0
- src/agents/idea_agent/utils/workflow/idea_helpers.py +478 -0
- src/agents/idea_agent/utils/workflow/idea_portfolio.py +422 -0
- src/agents/idea_agent/utils/workflow/idea_synthesis.py +482 -0
- src/agents/idea_agent/utils/workflow/ligagent_flow.py +581 -0
- src/agents/idea_agent/utils/workflow/ligagent_handlers.py +1836 -0
- src/agents/idea_agent/utils/workflow/ligagent_helpers.py +1331 -0
- src/agents/idea_agent/utils/workflow/ligagent_utils.py +322 -0
- src/agents/idea_agent/utils/workflow/mature_idea_sources.py +648 -0
- src/agents/idea_agent/utils/workflow/multimodal_data_anchoring.py +578 -0
- src/agents/idea_agent/utils/workflow/result_persistence.py +774 -0
- src/agents/idea_agent/utils/workflow/stage_contract.py +76 -0
- src/agents/idea_agent/utils/workflow/workflow_runtime.py +288 -0
- src/agents/research_plan_author/__init__.py +50 -0
- src/agents/research_plan_author/artifacts.py +270 -0
- src/agents/research_plan_author/authoring_blueprint.py +1246 -0
- src/agents/research_plan_author/bibtex_renderer.py +252 -0
- src/agents/research_plan_author/contract_repair.py +131 -0
- src/agents/research_plan_author/contracts.py +745 -0
- src/agents/research_plan_author/cross_section_editor.py +232 -0
- src/agents/research_plan_author/document_quality.py +987 -0
- src/agents/research_plan_author/idea_evolution.py +223 -0
- src/agents/research_plan_author/input_loader.py +76 -0
- src/agents/research_plan_author/latex_compiler.py +260 -0
- src/agents/research_plan_author/latex_safety.py +159 -0
- src/agents/research_plan_author/llm_json.py +74 -0
- src/agents/research_plan_author/markdown_renderer.py +275 -0
- src/agents/research_plan_author/pdf_validator.py +149 -0
- src/agents/research_plan_author/render.py +166 -0
- src/agents/research_plan_author/render_artifacts.py +187 -0
- src/agents/research_plan_author/run.py +765 -0
- src/agents/research_plan_author/run_logging.py +209 -0
- src/agents/research_plan_author/section_cache.py +184 -0
- src/agents/research_plan_author/section_composer.py +1764 -0
- src/agents/research_plan_author/section_router.py +209 -0
- src/agents/research_plan_author/semantic_validator.py +254 -0
- src/agents/research_plan_author/source_bundle.py +46 -0
- src/agents/research_plan_author/source_registry.py +208 -0
- src/agents/research_plan_author/survey_source_loader.py +137 -0
- src/agents/research_plan_author/template_adapter.py +173 -0
- src/agents/research_plan_author/template_profile.py +204 -0
- src/agents/research_plan_author/tex_renderer.py +496 -0
- src/agents/research_plan_author/theory_presentation.py +134 -0
- src/agents/research_plan_author/theory_spine.py +703 -0
- src/agents/survey_agent/Dockerfile +54 -0
- src/agents/survey_agent/README.md +350 -0
- src/agents/survey_agent/config/deep_survey.yaml +217 -0
- src/agents/survey_agent/config/deep_survey_batch.yaml +176 -0
- src/agents/survey_agent/config/deep_survey_fast.yaml +183 -0
- src/agents/survey_agent/config/evaluate_baseline.yaml +197 -0
- src/agents/survey_agent/config/outcomeRAG.yaml +159 -0
- src/agents/survey_agent/env_report.md +348 -0
- src/agents/survey_agent/modules/__init__.py +0 -0
- src/agents/survey_agent/modules/code_collector.py +2194 -0
- src/agents/survey_agent/modules/code_report_generator.py +1282 -0
- src/agents/survey_agent/modules/data_manager.py +1713 -0
- src/agents/survey_agent/modules/database.py +167 -0
- src/agents/survey_agent/modules/fulltext_download_cache.py +462 -0
- src/agents/survey_agent/modules/fulltext_http.py +134 -0
- src/agents/survey_agent/modules/fulltext_resolution.py +749 -0
- src/agents/survey_agent/modules/judge.py +434 -0
- src/agents/survey_agent/modules/outcome_RAG.py +236 -0
- src/agents/survey_agent/modules/paper_graph_retriever.py +1075 -0
- src/agents/survey_agent/modules/pe.py +1729 -0
- src/agents/survey_agent/modules/pseudo_creator.py +782 -0
- src/agents/survey_agent/modules/pseudo_reviser.py +537 -0
- src/agents/survey_agent/modules/refine_agent.py +1952 -0
- src/agents/survey_agent/modules/survey_generator.py +5691 -0
- src/agents/survey_agent/modules/survey_visualizer.py +1817 -0
- src/agents/survey_agent/modules/visual_prompts.py +327 -0
- src/agents/survey_agent/modules/work_analyzer.py +2750 -0
- src/agents/survey_agent/modules/work_collector.py +5649 -0
- src/agents/survey_agent/scripts/baseline_evaluation.py +411 -0
- src/agents/survey_agent/scripts/run_deep_survey.py +224 -0
- src/agents/survey_agent/scripts/run_deep_survey_adapter.py +407 -0
- src/agents/survey_agent/scripts/run_deep_survey_adapter_with_input.py +409 -0
- src/agents/survey_agent/scripts/run_deep_survey_batch.py +228 -0
- src/agents/survey_agent/scripts/run_deep_survey_batch_arg.py +243 -0
- src/agents/survey_agent/scripts/run_deep_survey_batch_settings.py +218 -0
- src/agents/survey_agent/scripts/run_keynotes_gen.py +128 -0
- src/agents/survey_agent/scripts/run_work_clusters.py +140 -0
- src/agents/survey_agent/utils/__init__.py +0 -0
- src/agents/survey_agent/utils/ablation_utils.py +317 -0
- src/agents/survey_agent/utils/api_call.py +2518 -0
- src/agents/survey_agent/utils/chat_utils.py +82 -0
- src/agents/survey_agent/utils/config_utils.py +70 -0
- src/agents/survey_agent/utils/convert_to_md.py +29 -0
- src/agents/survey_agent/utils/err_info.py +24 -0
- src/agents/survey_agent/utils/file_utils.py +176 -0
- src/agents/survey_agent/utils/gpu_utils.py +145 -0
- src/agents/survey_agent/utils/graph_visualizer.py +279 -0
- src/agents/survey_agent/utils/html_utils.py +181 -0
- src/agents/survey_agent/utils/latex_generator_intra_cluster.py +529 -0
- src/agents/survey_agent/utils/latex_generator_relation_table.py +193 -0
- src/agents/survey_agent/utils/mineru_section_packer.py +334 -0
- src/agents/survey_agent/utils/mineru_utils.py +396 -0
- src/agents/survey_agent/utils/paper.py +144 -0
- src/agents/survey_agent/utils/read_yaml.py +15 -0
- src/agents/survey_agent/utils/repo_utils.py +167 -0
- src/agents/survey_agent/utils/rich_logger.py +77 -0
- src/agents/survey_agent/utils/step2v2.py +874 -0
- src/agents/survey_agent/utils/step2v2_extractor.py +856 -0
- src/agents/survey_agent/utils/topic_survey_storage.py +309 -0
- src/agents/survey_agent/utils/utils.py +118 -0
- src/agents/survey_agent/utils/work.py +2 -0
- src/cli.py +1611 -0
- src/config/__init__.py +213 -0
- src/config/default.yaml +1122 -0
- src/harness/LICENSE +21 -0
- src/harness/VENDORED.md +14 -0
- src/harness/src/__init__.py +0 -0
- src/harness/src/openharness/__init__.py +0 -0
- src/harness/src/openharness/__main__.py +6 -0
- src/harness/src/openharness/api/__init__.py +21 -0
- src/harness/src/openharness/api/client.py +281 -0
- src/harness/src/openharness/api/codex_client.py +407 -0
- src/harness/src/openharness/api/copilot_auth.py +240 -0
- src/harness/src/openharness/api/copilot_client.py +134 -0
- src/harness/src/openharness/api/errors.py +19 -0
- src/harness/src/openharness/api/openai_client.py +577 -0
- src/harness/src/openharness/api/provider.py +186 -0
- src/harness/src/openharness/api/registry.py +437 -0
- src/harness/src/openharness/api/usage.py +17 -0
- src/harness/src/openharness/auth/__init__.py +29 -0
- src/harness/src/openharness/auth/external.py +610 -0
- src/harness/src/openharness/auth/flows.py +189 -0
- src/harness/src/openharness/auth/manager.py +482 -0
- src/harness/src/openharness/auth/storage.py +269 -0
- src/harness/src/openharness/autopilot/__init__.py +23 -0
- src/harness/src/openharness/autopilot/service.py +2239 -0
- src/harness/src/openharness/autopilot/types.py +91 -0
- src/harness/src/openharness/bridge/__init__.py +20 -0
- src/harness/src/openharness/bridge/manager.py +106 -0
- src/harness/src/openharness/bridge/session_runner.py +46 -0
- src/harness/src/openharness/bridge/types.py +37 -0
- src/harness/src/openharness/bridge/work_secret.py +41 -0
- src/harness/src/openharness/channels/UPSTREAM +6 -0
- src/harness/src/openharness/channels/__init__.py +22 -0
- src/harness/src/openharness/channels/adapter.py +131 -0
- src/harness/src/openharness/channels/bus/__init__.py +6 -0
- src/harness/src/openharness/channels/bus/events.py +38 -0
- src/harness/src/openharness/channels/bus/queue.py +44 -0
- src/harness/src/openharness/channels/impl/__init__.py +6 -0
- src/harness/src/openharness/channels/impl/base.py +141 -0
- src/harness/src/openharness/channels/impl/dingtalk.py +445 -0
- src/harness/src/openharness/channels/impl/discord.py +311 -0
- src/harness/src/openharness/channels/impl/email.py +410 -0
- src/harness/src/openharness/channels/impl/feishu.py +1342 -0
- src/harness/src/openharness/channels/impl/manager.py +257 -0
- src/harness/src/openharness/channels/impl/matrix.py +700 -0
- src/harness/src/openharness/channels/impl/mochat.py +897 -0
- src/harness/src/openharness/channels/impl/qq.py +141 -0
- src/harness/src/openharness/channels/impl/slack.py +284 -0
- src/harness/src/openharness/channels/impl/telegram.py +525 -0
- src/harness/src/openharness/channels/impl/whatsapp.py +159 -0
- src/harness/src/openharness/cli.py +2551 -0
- src/harness/src/openharness/commands/__init__.py +21 -0
- src/harness/src/openharness/commands/registry.py +2783 -0
- src/harness/src/openharness/config/__init__.py +34 -0
- src/harness/src/openharness/config/paths.py +160 -0
- src/harness/src/openharness/config/schema.py +119 -0
- src/harness/src/openharness/config/settings.py +1104 -0
- src/harness/src/openharness/coordinator/__init__.py +12 -0
- src/harness/src/openharness/coordinator/agent_definitions.py +975 -0
- src/harness/src/openharness/coordinator/coordinator_mode.py +520 -0
- src/harness/src/openharness/engine/__init__.py +80 -0
- src/harness/src/openharness/engine/cost_tracker.py +24 -0
- src/harness/src/openharness/engine/messages.py +222 -0
- src/harness/src/openharness/engine/query.py +1188 -0
- src/harness/src/openharness/engine/query_engine.py +313 -0
- src/harness/src/openharness/engine/stream_events.py +90 -0
- src/harness/src/openharness/hooks/__init__.py +50 -0
- src/harness/src/openharness/hooks/events.py +20 -0
- src/harness/src/openharness/hooks/executor.py +242 -0
- src/harness/src/openharness/hooks/hot_reload.py +31 -0
- src/harness/src/openharness/hooks/loader.py +68 -0
- src/harness/src/openharness/hooks/schemas.py +66 -0
- src/harness/src/openharness/hooks/types.py +38 -0
- src/harness/src/openharness/keybindings/__init__.py +14 -0
- src/harness/src/openharness/keybindings/default_bindings.py +11 -0
- src/harness/src/openharness/keybindings/loader.py +22 -0
- src/harness/src/openharness/keybindings/parser.py +18 -0
- src/harness/src/openharness/keybindings/resolver.py +13 -0
- src/harness/src/openharness/mcp/__init__.py +79 -0
- src/harness/src/openharness/mcp/client.py +298 -0
- src/harness/src/openharness/mcp/config.py +16 -0
- src/harness/src/openharness/mcp/types.py +76 -0
- src/harness/src/openharness/memory/__init__.py +25 -0
- src/harness/src/openharness/memory/agent.py +91 -0
- src/harness/src/openharness/memory/manager.py +183 -0
- src/harness/src/openharness/memory/memdir.py +52 -0
- src/harness/src/openharness/memory/migrate.py +137 -0
- src/harness/src/openharness/memory/paths.py +22 -0
- src/harness/src/openharness/memory/relevance.py +145 -0
- src/harness/src/openharness/memory/scan.py +116 -0
- src/harness/src/openharness/memory/schema.py +443 -0
- src/harness/src/openharness/memory/search.py +71 -0
- src/harness/src/openharness/memory/team.py +90 -0
- src/harness/src/openharness/memory/types.py +33 -0
- src/harness/src/openharness/memory/usage.py +153 -0
- src/harness/src/openharness/output_styles/__init__.py +5 -0
- src/harness/src/openharness/output_styles/loader.py +42 -0
- src/harness/src/openharness/permissions/__init__.py +26 -0
- src/harness/src/openharness/permissions/checker.py +200 -0
- src/harness/src/openharness/permissions/modes.py +13 -0
- src/harness/src/openharness/personalization/__init__.py +6 -0
- src/harness/src/openharness/personalization/extractor.py +138 -0
- src/harness/src/openharness/personalization/rules.py +64 -0
- src/harness/src/openharness/personalization/session_hook.py +65 -0
- src/harness/src/openharness/platforms.py +86 -0
- src/harness/src/openharness/plugins/__init__.py +53 -0
- src/harness/src/openharness/plugins/bundled/__init__.py +0 -0
- src/harness/src/openharness/plugins/installer.py +39 -0
- src/harness/src/openharness/plugins/loader.py +730 -0
- src/harness/src/openharness/plugins/schemas.py +24 -0
- src/harness/src/openharness/plugins/types.py +59 -0
- src/harness/src/openharness/prompts/__init__.py +14 -0
- src/harness/src/openharness/prompts/claudemd.py +48 -0
- src/harness/src/openharness/prompts/context.py +187 -0
- src/harness/src/openharness/prompts/environment.py +135 -0
- src/harness/src/openharness/prompts/system_prompt.py +109 -0
- src/harness/src/openharness/sandbox/Dockerfile +6 -0
- src/harness/src/openharness/sandbox/__init__.py +33 -0
- src/harness/src/openharness/sandbox/adapter.py +148 -0
- src/harness/src/openharness/sandbox/docker_backend.py +232 -0
- src/harness/src/openharness/sandbox/docker_image.py +103 -0
- src/harness/src/openharness/sandbox/path_validator.py +37 -0
- src/harness/src/openharness/sandbox/session.py +63 -0
- src/harness/src/openharness/services/__init__.py +30 -0
- src/harness/src/openharness/services/autodream/__init__.py +34 -0
- src/harness/src/openharness/services/autodream/backup.py +104 -0
- src/harness/src/openharness/services/autodream/lock.py +138 -0
- src/harness/src/openharness/services/autodream/prompt.py +128 -0
- src/harness/src/openharness/services/autodream/service.py +313 -0
- src/harness/src/openharness/services/compact/__init__.py +1725 -0
- src/harness/src/openharness/services/cron.py +137 -0
- src/harness/src/openharness/services/cron_scheduler.py +595 -0
- src/harness/src/openharness/services/lsp/__init__.py +216 -0
- src/harness/src/openharness/services/memory_extract/__init__.py +261 -0
- src/harness/src/openharness/services/oauth/__init__.py +0 -0
- src/harness/src/openharness/services/session_backend.py +97 -0
- src/harness/src/openharness/services/session_memory/__init__.py +139 -0
- src/harness/src/openharness/services/session_storage.py +230 -0
- src/harness/src/openharness/services/token_estimation.py +15 -0
- src/harness/src/openharness/services/tool_outputs.py +55 -0
- src/harness/src/openharness/skills/__init__.py +44 -0
- src/harness/src/openharness/skills/_frontmatter.py +97 -0
- src/harness/src/openharness/skills/bundled/__init__.py +75 -0
- src/harness/src/openharness/skills/bundled/content/commit.md +25 -0
- src/harness/src/openharness/skills/bundled/content/debug.md +25 -0
- src/harness/src/openharness/skills/bundled/content/diagnose.md +35 -0
- src/harness/src/openharness/skills/bundled/content/plan.md +39 -0
- src/harness/src/openharness/skills/bundled/content/review.md +33 -0
- src/harness/src/openharness/skills/bundled/content/simplify.md +26 -0
- src/harness/src/openharness/skills/bundled/content/skill-creator.md +175 -0
- src/harness/src/openharness/skills/bundled/content/test.md +38 -0
- src/harness/src/openharness/skills/loader.py +229 -0
- src/harness/src/openharness/skills/registry.py +29 -0
- src/harness/src/openharness/skills/types.py +24 -0
- src/harness/src/openharness/state/__init__.py +6 -0
- src/harness/src/openharness/state/app_state.py +30 -0
- src/harness/src/openharness/state/store.py +40 -0
- src/harness/src/openharness/swarm/__init__.py +70 -0
- src/harness/src/openharness/swarm/in_process.py +693 -0
- src/harness/src/openharness/swarm/lockfile.py +24 -0
- src/harness/src/openharness/swarm/mailbox.py +522 -0
- src/harness/src/openharness/swarm/permission_sync.py +1168 -0
- src/harness/src/openharness/swarm/registry.py +410 -0
- src/harness/src/openharness/swarm/spawn_utils.py +229 -0
- src/harness/src/openharness/swarm/subprocess_backend.py +171 -0
- src/harness/src/openharness/swarm/team_lifecycle.py +910 -0
- src/harness/src/openharness/swarm/types.py +398 -0
- src/harness/src/openharness/swarm/worktree.py +315 -0
- src/harness/src/openharness/tasks/__init__.py +18 -0
- src/harness/src/openharness/tasks/local_agent_task.py +28 -0
- src/harness/src/openharness/tasks/local_shell_task.py +17 -0
- src/harness/src/openharness/tasks/manager.py +475 -0
- src/harness/src/openharness/tasks/stop_task.py +11 -0
- src/harness/src/openharness/tasks/types.py +32 -0
- src/harness/src/openharness/themes/__init__.py +21 -0
- src/harness/src/openharness/themes/builtin.py +89 -0
- src/harness/src/openharness/themes/loader.py +55 -0
- src/harness/src/openharness/themes/schema.py +54 -0
- src/harness/src/openharness/tools/__init__.py +107 -0
- src/harness/src/openharness/tools/agent_tool.py +141 -0
- src/harness/src/openharness/tools/ask_user_question_tool.py +46 -0
- src/harness/src/openharness/tools/base.py +80 -0
- src/harness/src/openharness/tools/bash_tool.py +259 -0
- src/harness/src/openharness/tools/brief_tool.py +33 -0
- src/harness/src/openharness/tools/config_tool.py +54 -0
- src/harness/src/openharness/tools/cron_create_tool.py +105 -0
- src/harness/src/openharness/tools/cron_delete_tool.py +32 -0
- src/harness/src/openharness/tools/cron_list_tool.py +69 -0
- src/harness/src/openharness/tools/cron_toggle_tool.py +37 -0
- src/harness/src/openharness/tools/enter_plan_mode_tool.py +28 -0
- src/harness/src/openharness/tools/enter_worktree_tool.py +80 -0
- src/harness/src/openharness/tools/exit_plan_mode_tool.py +28 -0
- src/harness/src/openharness/tools/exit_worktree_tool.py +42 -0
- src/harness/src/openharness/tools/file_edit_tool.py +95 -0
- src/harness/src/openharness/tools/file_read_tool.py +72 -0
- src/harness/src/openharness/tools/file_write_tool.py +87 -0
- src/harness/src/openharness/tools/glob_tool.py +175 -0
- src/harness/src/openharness/tools/grep_tool.py +374 -0
- src/harness/src/openharness/tools/image_generation_tool.py +447 -0
- src/harness/src/openharness/tools/image_to_text_tool.py +237 -0
- src/harness/src/openharness/tools/list_mcp_resources_tool.py +36 -0
- src/harness/src/openharness/tools/lsp_tool.py +154 -0
- src/harness/src/openharness/tools/mcp_auth_tool.py +71 -0
- src/harness/src/openharness/tools/mcp_tool.py +72 -0
- src/harness/src/openharness/tools/notebook_edit_tool.py +97 -0
- src/harness/src/openharness/tools/read_mcp_resource_tool.py +38 -0
- src/harness/src/openharness/tools/remote_trigger_tool.py +74 -0
- src/harness/src/openharness/tools/send_message_tool.py +58 -0
- src/harness/src/openharness/tools/skill_tool.py +43 -0
- src/harness/src/openharness/tools/sleep_tool.py +32 -0
- src/harness/src/openharness/tools/task_create_tool.py +56 -0
- src/harness/src/openharness/tools/task_get_tool.py +33 -0
- src/harness/src/openharness/tools/task_list_tool.py +35 -0
- src/harness/src/openharness/tools/task_output_tool.py +35 -0
- src/harness/src/openharness/tools/task_stop_tool.py +30 -0
- src/harness/src/openharness/tools/task_update_tool.py +50 -0
- src/harness/src/openharness/tools/team_create_tool.py +31 -0
- src/harness/src/openharness/tools/team_delete_tool.py +30 -0
- src/harness/src/openharness/tools/todo_write_tool.py +46 -0
- src/harness/src/openharness/tools/tool_search_tool.py +38 -0
- src/harness/src/openharness/tools/web_fetch_tool.py +117 -0
- src/harness/src/openharness/tools/web_search_tool.py +119 -0
- src/harness/src/openharness/ui/__init__.py +5 -0
- src/harness/src/openharness/ui/app.py +320 -0
- src/harness/src/openharness/ui/backend_host.py +941 -0
- src/harness/src/openharness/ui/coordinator_drain.py +198 -0
- src/harness/src/openharness/ui/input.py +32 -0
- src/harness/src/openharness/ui/output.py +265 -0
- src/harness/src/openharness/ui/permission_dialog.py +14 -0
- src/harness/src/openharness/ui/protocol.py +247 -0
- src/harness/src/openharness/ui/react_launcher.py +179 -0
- src/harness/src/openharness/ui/runtime.py +799 -0
- src/harness/src/openharness/ui/textual_app.py +495 -0
- src/harness/src/openharness/utils/__init__.py +0 -0
- src/harness/src/openharness/utils/file_lock.py +86 -0
- src/harness/src/openharness/utils/fs.py +98 -0
- src/harness/src/openharness/utils/helpers.py +77 -0
- src/harness/src/openharness/utils/network_guard.py +340 -0
- src/harness/src/openharness/utils/shell.py +147 -0
- src/harness/src/openharness/vim/__init__.py +5 -0
- src/harness/src/openharness/vim/transitions.py +8 -0
- src/harness/src/openharness/voice/__init__.py +7 -0
- src/harness/src/openharness/voice/keyterms.py +10 -0
- src/harness/src/openharness/voice/stream_stt.py +8 -0
- src/harness/src/openharness/voice/voice_mode.py +44 -0
- src/llm/__init__.py +29 -0
- src/llm/image_generation.py +402 -0
- src/llm/provider_registry.py +419 -0
- src/llm/runtime_env.py +64 -0
- src/llm/structured_output.py +131 -0
- src/llm/vision.py +198 -0
- src/memory/__init__.py +2 -0
- src/memory/api/__init__.py +1 -0
- src/memory/api/base_memory_system_api.py +98 -0
- src/memory/api/base_symbolic_memory_system_api.py +190 -0
- src/memory/api/base_vector_memory_system_api.py +116 -0
- src/memory/api/faiss_memory_system_api.py +228 -0
- src/memory/api/slot_process_api.py +827 -0
- src/memory/api/symbolic_memory_system_api.py +572 -0
- src/memory/memory_system/__init__.py +48 -0
- src/memory/memory_system/component_taxonomy.py +430 -0
- src/memory/memory_system/llm.py +437 -0
- src/memory/memory_system/models.py +168 -0
- src/memory/memory_system/user_prompt.py +418 -0
- src/memory/memory_system/utils.py +282 -0
- src/memory/memory_system/vectorstore.py +311 -0
- src/memory/memory_system/working_slot.py +99 -0
- src/pipeline/__init__.py +129 -0
- src/pipeline/contracts.py +531 -0
- src/pipeline/discipline_taxonomy.py +916 -0
- src/pipeline/evidence_coverage_ledger.py +1150 -0
- src/pipeline/evidence_refinement.py +620 -0
- src/pipeline/experiment_to_symbolic.py +137 -0
- src/pipeline/multimodal_evidence/__init__.py +28 -0
- src/pipeline/multimodal_evidence/capabilities.py +107 -0
- src/pipeline/multimodal_evidence/claims.py +135 -0
- src/pipeline/multimodal_evidence/contract.py +291 -0
- src/pipeline/multimodal_evidence/data_sh_compiler.py +505 -0
- src/pipeline/multimodal_evidence/handoff_binding.py +135 -0
- src/pipeline/multimodal_evidence/manifest.py +254 -0
- src/pipeline/multimodal_evidence/native_analysis.py +479 -0
- src/pipeline/multimodal_evidence/perception.py +277 -0
- src/pipeline/multimodal_evidence/query_binding.py +65 -0
- src/pipeline/multimodal_evidence/rendering.py +120 -0
- src/pipeline/multimodal_evidence/safety.py +42 -0
- src/pipeline/multimodal_evidence/sampling.py +69 -0
- src/pipeline/multimodal_evidence/service.py +148 -0
- src/pipeline/multimodal_evidence/survey_integration.py +460 -0
- src/pipeline/paper_identity.py +52 -0
- src/pipeline/research_design_inventory.py +338 -0
- src/pipeline/research_domain_resolution.py +669 -0
- src/pipeline/research_identity.py +548 -0
- src/pipeline/research_question_contract.py +646 -0
- src/pipeline/retrieval_lanes.py +889 -0
- src/pipeline/run_loop.py +862 -0
- src/pipeline/science_events.py +30 -0
- src/pipeline/science_manifests.py +602 -0
- src/pipeline/science_run.py +918 -0
- src/pipeline/science_stages.py +709 -0
- src/pipeline/science_workflow.py +807 -0
- src/pipeline/sh_cluster_projection.py +306 -0
- src/pipeline/sh_graph_provenance.py +648 -0
- src/pipeline/subhypothesis_decomposition.py +392 -0
- src/pipeline/subhypothesis_evidence.py +856 -0
- src/pipeline/survey_evidence_plan.py +858 -0
- src/pipeline/survey_gap_adjudication.py +647 -0
- src/pipeline/survey_gap_candidates.py +840 -0
- src/pipeline/survey_gap_ledger.py +683 -0
- src/pipeline/survey_gap_triage.py +401 -0
- src/pipeline/survey_handoff_persistence.py +481 -0
- src/pipeline/survey_handoff_projection.py +457 -0
- src/pipeline/survey_idea_handoff.py +1112 -0
- src/pipeline/survey_idea_loader.py +289 -0
- src/research_run_ids.py +11 -0
|
@@ -0,0 +1,856 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Step2v2 Extractor Module - Refactored for compatibility with ChatAgent
|
|
3
|
+
|
|
4
|
+
This module provides functions to extract structured information from academic papers.
|
|
5
|
+
It can be used with the project's ChatAgent via batch_remote_chat_with_retry.
|
|
6
|
+
|
|
7
|
+
Usage:
|
|
8
|
+
1. Call extract_paper_info_batch() to extract info for multiple papers
|
|
9
|
+
2. The function handles prompt building, API calls, and result aggregation internally
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
import os
|
|
13
|
+
import json
|
|
14
|
+
import re
|
|
15
|
+
from typing import Dict, List, Optional, Tuple, Any
|
|
16
|
+
|
|
17
|
+
from utils.utils import extract_json
|
|
18
|
+
|
|
19
|
+
# ================= CONSTANTS =================
|
|
20
|
+
|
|
21
|
+
ARXIV_DOMAINS = [
|
|
22
|
+
"cs.CV", "cs.CL", "cs.LG", "cs.AI", "cs.RO", "cs.NE", "stat.ML", "cs.MA",
|
|
23
|
+
"cs.DC", "cs.OS", "cs.AR", "cs.NI", "cs.PL", "cs.SE", "cs.DB", "cs.PF",
|
|
24
|
+
"cs.CC", "cs.DS", "cs.LO", "cs.IT", "cs.CR", "cs.GT",
|
|
25
|
+
"cs.HC", "cs.SI", "cs.CY", "cs.IR", "cs.MM", "cs.DL",
|
|
26
|
+
"cs.CE", "cs.CG", "cs.DM", "cs.ET", "cs.FL", "cs.GL",
|
|
27
|
+
"cs.GR", "cs.MS", "cs.NA", "cs.OH", "cs.SC", "cs.SD", "cs.SY",
|
|
28
|
+
"Hybrid", "Others"
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
PAPER_TYPES = [
|
|
32
|
+
"Methodology", "System Design", "Benchmark/Dataset",
|
|
33
|
+
"Theoretical Proof", "Empirical Study", "Survey/Review",
|
|
34
|
+
"Application", "Position Paper", "Hybrid",
|
|
35
|
+
"Resource Paper", "Reproducibility Study", "Negative Results",
|
|
36
|
+
"Tutorial/Educational", "Others"
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
METRIC_BLACKLIST = {
|
|
40
|
+
"accuracy", "precision", "recall", "f1", "auc", "roc", "map", "iou", "psnr", "ssim",
|
|
41
|
+
"fid", "inception score", "bleu", "rouge", "meteor", "cider", "fps", "latency",
|
|
42
|
+
"throughput", "flops", "parameters", "training time", "convergence", "error rate",
|
|
43
|
+
"speed", "cost", "memory", "loss", "perplexity", "top-1", "top-5", "mae", "rmse",
|
|
44
|
+
"validity", "novelty", "uniqueness", "diversity", "baseline", "sota", "method",
|
|
45
|
+
"model", "algorithm", "previous work", "prior art", "ablation", "variant", "proposed"
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
# ================= UTILITY FUNCTIONS =================
|
|
50
|
+
|
|
51
|
+
def clean_title_latex(title: str) -> str:
|
|
52
|
+
"""Clean LaTeX special characters from title."""
|
|
53
|
+
if not title: return "Unknown Title"
|
|
54
|
+
t = re.sub(r'^\d+(\.\d+)*\s+', '', title)
|
|
55
|
+
t = re.sub(r'[$\\{}"]', '', t)
|
|
56
|
+
t = re.sub(r'\s+', ' ', t).strip()
|
|
57
|
+
return t
|
|
58
|
+
|
|
59
|
+
def extract_regex_candidates(full_text: str) -> Dict[str, List[str]]:
|
|
60
|
+
"""Extract candidate methods and baselines using regex patterns."""
|
|
61
|
+
candidates = {"methods": set(), "baselines": set()}
|
|
62
|
+
|
|
63
|
+
method_pattern = re.compile(
|
|
64
|
+
r"(?:proposed|our|new|introduce|present)\s+(?:method|framework|algorithm|network|model)?\s*([A-Z][A-Za-z0-9\-]{2,15})",
|
|
65
|
+
re.MULTILINE
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
baseline_pattern = re.compile(
|
|
69
|
+
r"(?:compare(?:s|d)?\s+(?:with|to|against)|outperform(?:s|ed)|surpass(?:es|ed)|superior\s+to|better\s+than|following|adopted\s+from|baseline|built\s+upon|extends?|evaluates?|analyzes?|prior\s+work|existing\s+method)\s+([A-Z][A-Za-z0-9\-]{2,15})",
|
|
70
|
+
re.IGNORECASE | re.MULTILINE
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
for m in method_pattern.findall(full_text):
|
|
74
|
+
if len(m) > 2 and m.lower() not in METRIC_BLACKLIST:
|
|
75
|
+
candidates["methods"].add(m)
|
|
76
|
+
for b in baseline_pattern.findall(full_text):
|
|
77
|
+
if len(b) > 2 and b.lower() not in METRIC_BLACKLIST:
|
|
78
|
+
candidates["baselines"].add(b)
|
|
79
|
+
|
|
80
|
+
return {"methods": list(candidates["methods"]), "baselines": list(candidates["baselines"])}
|
|
81
|
+
|
|
82
|
+
def mark_entities_in_text(full_text: str, entity_list: List[str], marker_prefix: str) -> str:
|
|
83
|
+
"""Mark entities in text with special markers."""
|
|
84
|
+
marked_text = full_text
|
|
85
|
+
for entity in entity_list:
|
|
86
|
+
if not entity or len(entity) < 3:
|
|
87
|
+
continue
|
|
88
|
+
escaped = re.escape(entity)
|
|
89
|
+
pattern = r'\b' + escaped + r'\b'
|
|
90
|
+
replacement = f"[{marker_prefix}:{entity}]"
|
|
91
|
+
marked_text = re.sub(pattern, replacement, marked_text, count=1, flags=re.IGNORECASE)
|
|
92
|
+
return marked_text
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
# ================= PROMPT BUILDERS =================
|
|
96
|
+
|
|
97
|
+
def build_main_extraction_prompt(
|
|
98
|
+
markdown_text: str,
|
|
99
|
+
title: str,
|
|
100
|
+
regex_candidates: dict,
|
|
101
|
+
*,
|
|
102
|
+
section_context: dict | None = None,
|
|
103
|
+
) -> Tuple[str, str]:
|
|
104
|
+
"""
|
|
105
|
+
Build main extraction prompt for a single paper.
|
|
106
|
+
|
|
107
|
+
Returns:
|
|
108
|
+
Tuple of (system_prompt, user_prompt)
|
|
109
|
+
"""
|
|
110
|
+
domain_str = ", ".join(ARXIV_DOMAINS)
|
|
111
|
+
type_str = ", ".join(PAPER_TYPES)
|
|
112
|
+
|
|
113
|
+
marked_text = mark_entities_in_text(markdown_text, regex_candidates['methods'], "HINT_METHOD")
|
|
114
|
+
|
|
115
|
+
core_type_reference = """
|
|
116
|
+
Core Contribution Type Reference (Choose ONE single word):
|
|
117
|
+
1. Methodological: Algorithm, Architecture, Framework, TrainingMethod, InferenceMethod, LossFunction, OptimizationTechnique
|
|
118
|
+
2. System/Tool: System, Infrastructure, Tool, Library, Platform
|
|
119
|
+
3. Data/Evaluation: Dataset, Benchmark, DataAugmentation, AnnotationScheme, EvaluationMetric, EvaluationProtocol
|
|
120
|
+
4. Theoretical: TheoreticalFramework, TheoreticalProof, MathematicalFormulation, ComplexityAnalysis
|
|
121
|
+
5. Analytical: EmpiricalAnalysis, ComparativeAnalysis, AblationAnalysis, ErrorAnalysis, Survey, Taxonomy
|
|
122
|
+
6. Application: Application, CaseStudy, DomainAdaptation
|
|
123
|
+
7. Others: Hybrid, Others
|
|
124
|
+
|
|
125
|
+
OUTPUT FORMAT: Single word only (e.g., Algorithm, NOT Type: Algorithm)
|
|
126
|
+
"""
|
|
127
|
+
|
|
128
|
+
system = f"""You are a Senior Research Analyst extracting structured metadata from academic papers.
|
|
129
|
+
|
|
130
|
+
CRITICAL GROUNDING RULES:
|
|
131
|
+
1. Insight: Must provide INDEPENDENT ANALYSIS beyond summary. Describe prerequisites, trade-offs, design choices, or potential defects. DO NOT copy summary or quote.
|
|
132
|
+
2. Quote: Must be VERBATIM text from the original paper. Use ... for exact excerpts. DO NOT paraphrase or fabricate.
|
|
133
|
+
3. Summary: Concise factual description in natural sentence form.
|
|
134
|
+
4. Keywords: Concept words used for COARSE-GRAINED RETRIEVAL and filtering. Choose representative terms that capture the essence for search/matching.
|
|
135
|
+
|
|
136
|
+
PRIORITY: RECALL - Extract ALL relevant entities (cores, components, problems, innovations, limitations, future work). Do not omit items due to uncertainty.
|
|
137
|
+
|
|
138
|
+
Core vs Component Granularity Rules:
|
|
139
|
+
- Core Contribution: The LARGEST, TOP-LEVEL contribution that is NOT contained by any other entity. This is the root method/system/dataset proposed.
|
|
140
|
+
Example: Swin Transformer (the overall architecture)
|
|
141
|
+
Characteristics: Has unique name, explicitly claimed as main contribution, can stand alone
|
|
142
|
+
|
|
143
|
+
- Component: ALL sub-elements, modules, techniques, or building blocks that are PART OF a Core Contribution.
|
|
144
|
+
Example: Shifted Window Mechanism, Patch Merging Layer (parts of Swin Transformer)
|
|
145
|
+
Characteristics: Cannot exist independently without the Core, implements specific functionality
|
|
146
|
+
|
|
147
|
+
If unsure: Ask Can this exist independently, or is it always part of something bigger?
|
|
148
|
+
- Independent -> Core
|
|
149
|
+
- Part of bigger system -> Component
|
|
150
|
+
|
|
151
|
+
Text Marking System:
|
|
152
|
+
You will see markers like [HINT_METHOD:MethodName] in the text. These are SUGGESTIONS from pattern matching.
|
|
153
|
+
- They may contain false positives or miss important entities
|
|
154
|
+
- Use them to guide attention but read the FULL paper independently
|
|
155
|
+
- Extract ALL relevant entities regardless of whether they have markers
|
|
156
|
+
|
|
157
|
+
Few-Shot Examples:
|
|
158
|
+
|
|
159
|
+
Example 1: Clear Core-Component Hierarchy
|
|
160
|
+
Paper: Swin Transformer: Hierarchical Vision Transformer using Shifted Windows
|
|
161
|
+
|
|
162
|
+
Core Contribution:
|
|
163
|
+
name: Swin Transformer
|
|
164
|
+
acronym: SwinT
|
|
165
|
+
type: Architecture
|
|
166
|
+
keywords: [hierarchical transformer, shifted windows, vision backbone]
|
|
167
|
+
summary: Hierarchical vision transformer using shifted windows for efficient attention
|
|
168
|
+
insight: Trade-off: Achieves O(n) complexity via window-based computation but sacrifices some long-range modeling capability compared to full self-attention
|
|
169
|
+
quote: We propose Swin Transformer, a hierarchical Transformer whose representation is computed with shifted windows
|
|
170
|
+
|
|
171
|
+
Components (ALL parts of Swin Transformer):
|
|
172
|
+
1. name: Shifted Window Mechanism
|
|
173
|
+
acronym: null
|
|
174
|
+
related_to_core: Swin Transformer
|
|
175
|
+
keywords: [window attention, cross-window connection]
|
|
176
|
+
summary: Window-based self-attention with shifting for cross-window connections
|
|
177
|
+
insight: Design choice: 7x7 window balances efficiency and receptive field. Potential defect: Window boundaries may cause artifacts for objects spanning multiple windows
|
|
178
|
+
quote: The shifted windowing scheme bridges the windows of the preceding layer
|
|
179
|
+
|
|
180
|
+
2. name: Patch Merging Layer
|
|
181
|
+
acronym: null
|
|
182
|
+
related_to_core: Swin Transformer
|
|
183
|
+
keywords: [downsampling, hierarchical features]
|
|
184
|
+
summary: Downsampling layer that concatenates neighboring patch features
|
|
185
|
+
insight: Design choice: 2x2 merging reduces resolution while doubling channels. Potential defect: Loses fine-grained spatial information needed for dense prediction
|
|
186
|
+
quote: The patch merging layer concatenates the features of each group of 2x2 neighboring patches
|
|
187
|
+
|
|
188
|
+
Example 2: Multiple Cores
|
|
189
|
+
Paper proposes BOTH a new method AND a new dataset:
|
|
190
|
+
|
|
191
|
+
Core 1:
|
|
192
|
+
name: RainNet
|
|
193
|
+
acronym: null
|
|
194
|
+
type: Algorithm
|
|
195
|
+
keywords: [rain removal, weather robustness]
|
|
196
|
+
|
|
197
|
+
Core 2:
|
|
198
|
+
name: RainCityscapes
|
|
199
|
+
acronym: null
|
|
200
|
+
type: Dataset
|
|
201
|
+
keywords: [rainy driving, synthetic weather]
|
|
202
|
+
|
|
203
|
+
Component of Core 1:
|
|
204
|
+
name: Weather Augmentation Module
|
|
205
|
+
acronym: WAM
|
|
206
|
+
related_to_core: RainNet
|
|
207
|
+
keywords: [data augmentation, rain synthesis]
|
|
208
|
+
"""
|
|
209
|
+
|
|
210
|
+
section_context = section_context or {}
|
|
211
|
+
included_headings = str(section_context.get("included_headings") or "")
|
|
212
|
+
omitted_headings = str(section_context.get("omitted_headings") or "")
|
|
213
|
+
packet_notice = ""
|
|
214
|
+
source_label = "FULL PAPER TEXT"
|
|
215
|
+
if included_headings:
|
|
216
|
+
source_label = "COMPLETE SECTIONS FROM THE PAPER"
|
|
217
|
+
packet_notice = f"""
|
|
218
|
+
IMPORTANT SECTION-PACKET BOUNDARY:
|
|
219
|
+
The source text contains only the following complete sections:
|
|
220
|
+
{included_headings}
|
|
221
|
+
|
|
222
|
+
The following body sections are not in this request:
|
|
223
|
+
{omitted_headings or '- (none)'}
|
|
224
|
+
|
|
225
|
+
Do not infer results, limitations, or entities from omitted sections. Extract only
|
|
226
|
+
evidence explicitly present in the complete sections supplied below.
|
|
227
|
+
"""
|
|
228
|
+
|
|
229
|
+
user = f"""
|
|
230
|
+
{core_type_reference}
|
|
231
|
+
|
|
232
|
+
{packet_notice}
|
|
233
|
+
{source_label} (Some entities marked with [HINT_METHOD:...] as suggestions only):
|
|
234
|
+
{marked_text}
|
|
235
|
+
|
|
236
|
+
Task: Extract structured information for paper titled "{title}"
|
|
237
|
+
|
|
238
|
+
Output JSON Schema (FOLLOW THIS EXACT ATTRIBUTE ORDER):
|
|
239
|
+
{{
|
|
240
|
+
"metadata": {{
|
|
241
|
+
"title": "str (paper title, use EXACT title provided in the task)",
|
|
242
|
+
"domain": "str (from: {domain_str})",
|
|
243
|
+
"paper_type": "str (from: {type_str})",
|
|
244
|
+
"structured_summary": {{
|
|
245
|
+
"background": "str",
|
|
246
|
+
"method": "str",
|
|
247
|
+
"result": "str"
|
|
248
|
+
}},
|
|
249
|
+
"code_url": "str or null"
|
|
250
|
+
}},
|
|
251
|
+
"problems": [
|
|
252
|
+
{{
|
|
253
|
+
"keywords": ["str"],
|
|
254
|
+
"summary": "str",
|
|
255
|
+
"insight": "str (MUST be independent analysis)",
|
|
256
|
+
"quote": "str (MUST be verbatim)",
|
|
257
|
+
"related_to_core": "str"
|
|
258
|
+
}}
|
|
259
|
+
],
|
|
260
|
+
"core_contributions": [
|
|
261
|
+
{{
|
|
262
|
+
"name": "str (TOP-LEVEL entity)",
|
|
263
|
+
"acronym": "str or null",
|
|
264
|
+
"type": "str (SINGLE WORD)",
|
|
265
|
+
"keywords": ["str"],
|
|
266
|
+
"summary": "str",
|
|
267
|
+
"insight": "str (prerequisites, trade-offs, design rationale)",
|
|
268
|
+
"quote": "str"
|
|
269
|
+
}}
|
|
270
|
+
],
|
|
271
|
+
"core_relations": [
|
|
272
|
+
{{
|
|
273
|
+
"source": "str (core name)",
|
|
274
|
+
"target": "str (core name)",
|
|
275
|
+
"keywords": ["str"],
|
|
276
|
+
"summary": "str (natural sentence)",
|
|
277
|
+
"insight": "str (why relationship exists)",
|
|
278
|
+
"quote": "str"
|
|
279
|
+
}}
|
|
280
|
+
],
|
|
281
|
+
"components": [
|
|
282
|
+
{{
|
|
283
|
+
"name": "str (MUST NOT be same as core name)",
|
|
284
|
+
"acronym": "str or null",
|
|
285
|
+
"related_to_core": "str (MUST link to parent Core)",
|
|
286
|
+
"keywords": ["str"],
|
|
287
|
+
"summary": "str",
|
|
288
|
+
"insight": "str (MUST include design choices AND potential defects)",
|
|
289
|
+
"quote": "str"
|
|
290
|
+
}}
|
|
291
|
+
],
|
|
292
|
+
"innovations": [
|
|
293
|
+
{{
|
|
294
|
+
"keywords": ["str"],
|
|
295
|
+
"summary": "str",
|
|
296
|
+
"insight": "str",
|
|
297
|
+
"quote": "str",
|
|
298
|
+
"related_to_core": "str"
|
|
299
|
+
}}
|
|
300
|
+
],
|
|
301
|
+
"limitations": [
|
|
302
|
+
{{
|
|
303
|
+
"keywords": ["str"],
|
|
304
|
+
"summary": "str",
|
|
305
|
+
"insight": "str",
|
|
306
|
+
"quote": "str",
|
|
307
|
+
"related_to_core": "str"
|
|
308
|
+
}}
|
|
309
|
+
],
|
|
310
|
+
"future_work": [
|
|
311
|
+
{{
|
|
312
|
+
"keywords": ["str"],
|
|
313
|
+
"summary": "str",
|
|
314
|
+
"insight": "str",
|
|
315
|
+
"quote": "str",
|
|
316
|
+
"related_to_core": "str"
|
|
317
|
+
}}
|
|
318
|
+
]
|
|
319
|
+
}}
|
|
320
|
+
|
|
321
|
+
CRITICAL REMINDERS:
|
|
322
|
+
1. PRIORITY: RECALL - Extract ALL entities, even if uncertain
|
|
323
|
+
2. Core vs Component: Use hierarchy rules above
|
|
324
|
+
3. Type field: Single word only
|
|
325
|
+
4. Insight: Independent analysis, not copy of summary/quote
|
|
326
|
+
5. Quote: Verbatim text with ... markers
|
|
327
|
+
6. Components: MUST discuss potential defects
|
|
328
|
+
7. Keywords: Choose terms for RETRIEVAL and FILTERING purposes
|
|
329
|
+
8. Attribute order: MUST follow schema order exactly (keywords first, then summary, insight, quote)
|
|
330
|
+
9. Ignore [HINT_METHOD:...] markers in your output
|
|
331
|
+
|
|
332
|
+
Return JSON only:"""
|
|
333
|
+
|
|
334
|
+
return system, user
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
def build_baseline_extraction_prompt(markdown_text: str, core_names: List[str], regex_candidates: dict) -> Tuple[str, str]:
|
|
338
|
+
"""
|
|
339
|
+
Build baseline/dataset extraction prompt for a single paper.
|
|
340
|
+
|
|
341
|
+
Returns:
|
|
342
|
+
Tuple of (system_prompt, user_prompt)
|
|
343
|
+
"""
|
|
344
|
+
marked_text = mark_entities_in_text(markdown_text, regex_candidates['baselines'], "HINT_BASELINE")
|
|
345
|
+
|
|
346
|
+
system = """You are a Research Graph Builder focusing on relationship extraction.
|
|
347
|
+
|
|
348
|
+
CRITICAL: For Baselines and Datasets, the summary/insight/quote fields describe THE RELATIONSHIP/COMPARISON, NOT the entity itself.
|
|
349
|
+
|
|
350
|
+
PRIORITY: RECALL > PRECISION
|
|
351
|
+
Your PRIMARY GOAL is to extract ALL baselines and datasets mentioned, especially from:
|
|
352
|
+
- Experimental results (tables, figures)
|
|
353
|
+
- Related Work section
|
|
354
|
+
- Appendix (supplementary experiments)
|
|
355
|
+
- Theoretical comparisons (complexity analysis)
|
|
356
|
+
|
|
357
|
+
It is BETTER to include a questionable baseline than to miss a real one.
|
|
358
|
+
|
|
359
|
+
Text Marking System:
|
|
360
|
+
You will see markers like [HINT_BASELINE:MethodName] - these are SUGGESTIONS only.
|
|
361
|
+
Read Experiments, Related Work, and Appendix thoroughly to find ALL baselines.
|
|
362
|
+
|
|
363
|
+
Keywords Usage:
|
|
364
|
+
Keywords should capture key concepts for COARSE-GRAINED RETRIEVAL. Choose representative terms for filtering and search.
|
|
365
|
+
|
|
366
|
+
Example Baseline Entry:
|
|
367
|
+
{
|
|
368
|
+
"name": "ResNet-50",
|
|
369
|
+
"acronym": null,
|
|
370
|
+
"related_to_core": "Swin Transformer",
|
|
371
|
+
"keywords": ["residual network", "image classification"],
|
|
372
|
+
"summary": "Our SwinT outperforms this baseline by 3.2 percent on ImageNet top-1 accuracy",
|
|
373
|
+
"metrics": ["Top-1 Accuracy", "Top-5 Accuracy"],
|
|
374
|
+
"insight": "Performance gap stems from ResNet lack of long-range modeling vs attention mechanisms",
|
|
375
|
+
"quote": "Our method achieves 82.1 percent top-1 accuracy, surpassing ResNet-50 78.9 percent"
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
Example Dataset Entry:
|
|
379
|
+
{
|
|
380
|
+
"name": "ImageNet-1K",
|
|
381
|
+
"acronym": "IN-1K",
|
|
382
|
+
"related_to_core": "Swin Transformer",
|
|
383
|
+
"keywords": ["image classification", "large-scale benchmark"],
|
|
384
|
+
"summary": "Primary benchmark used to evaluate classification performance",
|
|
385
|
+
"metrics": ["Top-1 Accuracy", "Top-5 Accuracy"],
|
|
386
|
+
"insight": "ImageNet diversity makes it the de facto standard, though class distribution may not reflect real-world scenarios",
|
|
387
|
+
"quote": "We evaluate on ImageNet-1K ILSVRC2012 validation set"
|
|
388
|
+
}"""
|
|
389
|
+
|
|
390
|
+
user = f"""
|
|
391
|
+
Core Methods Proposed in THIS Paper (DO NOT include as baselines): {json.dumps(core_names)}
|
|
392
|
+
|
|
393
|
+
FULL PAPER TEXT (Some baselines marked with [HINT_BASELINE:...] as suggestions):
|
|
394
|
+
Focus especially on:
|
|
395
|
+
- Experimental Results sections
|
|
396
|
+
- Related Work section
|
|
397
|
+
- Appendix / Supplementary Material
|
|
398
|
+
- Theoretical Comparisons
|
|
399
|
+
|
|
400
|
+
{marked_text}
|
|
401
|
+
|
|
402
|
+
Task: Extract ALL baselines and datasets with MAXIMUM RECALL.
|
|
403
|
+
|
|
404
|
+
PRIORITY: RECALL - When in doubt, INCLUDE the baseline. Missing a baseline is worse than false positive.
|
|
405
|
+
|
|
406
|
+
What is a Baseline (Expanded):
|
|
407
|
+
1. Competitors: Methods explicitly compared in result tables
|
|
408
|
+
2. Predecessors: Methods this work builds upon, improves, or fixes
|
|
409
|
+
3. Related Work: Methods discussed as alternatives or inspiration
|
|
410
|
+
4. Theoretical Comparisons: Methods compared in complexity analysis
|
|
411
|
+
5. Appendix Comparisons: Additional baselines in supplementary experiments
|
|
412
|
+
6. For Dataset Papers: Previous datasets compared OR models evaluated on new benchmark
|
|
413
|
+
7. For Analysis Papers: Systems/methods being analyzed
|
|
414
|
+
8. Ablation Variants: Simplified versions of proposed method (e.g., Ours w/o attention)
|
|
415
|
+
|
|
416
|
+
Naming Convention:
|
|
417
|
+
- Prioritize Method Name (e.g., SimCLR, Faster R-CNN, ImageNet-1K)
|
|
418
|
+
- Only use Author Name (e.g., He et al.) IF method has no specific name
|
|
419
|
+
- For ablations: Use descriptive name (e.g., SwinT w/o shifted windows)
|
|
420
|
+
|
|
421
|
+
CONSTRAINT:
|
|
422
|
+
Baselines must ONLY contain PREVIOUS EXISTING ENTITIES or ABLATION VARIANTS.
|
|
423
|
+
NEVER include full Core Contributions from THIS paper ({core_names}).
|
|
424
|
+
|
|
425
|
+
Output JSON Schema (FOLLOW THIS EXACT ATTRIBUTE ORDER):
|
|
426
|
+
{{
|
|
427
|
+
"baselines": [
|
|
428
|
+
{{
|
|
429
|
+
"name": "str",
|
|
430
|
+
"acronym": "str or null",
|
|
431
|
+
"related_to_core": "str (which core compared to)",
|
|
432
|
+
"keywords": ["str"],
|
|
433
|
+
"summary": "str (natural sentence about relationship)",
|
|
434
|
+
"metrics": ["str"] or null,
|
|
435
|
+
"insight": "str (WHY performance gap or relationship exists)",
|
|
436
|
+
"quote": "str (evidence)"
|
|
437
|
+
}}
|
|
438
|
+
],
|
|
439
|
+
"datasets": [
|
|
440
|
+
{{
|
|
441
|
+
"name": "str",
|
|
442
|
+
"acronym": "str or null",
|
|
443
|
+
"related_to_core": "str",
|
|
444
|
+
"keywords": ["str"],
|
|
445
|
+
"summary": "str (how dataset is used)",
|
|
446
|
+
"metrics": ["str"] or null,
|
|
447
|
+
"insight": "str (why chosen, what reveals)",
|
|
448
|
+
"quote": "str"
|
|
449
|
+
}}
|
|
450
|
+
]
|
|
451
|
+
}}
|
|
452
|
+
|
|
453
|
+
CRITICAL REMINDERS:
|
|
454
|
+
1. PRIORITY: RECALL - Extract ALL from experiments, related work, appendix, theory
|
|
455
|
+
2. summary/insight/quote: Describe THE EDGE (relationship), not node (entity)
|
|
456
|
+
3. metrics: List of metric NAMES only (e.g., [Accuracy, F1]), OR null if not applicable
|
|
457
|
+
4. Attribute order: MUST follow schema (name, acronym, related_to_core, keywords, summary, metrics, insight, quote)
|
|
458
|
+
5. Keywords: Choose terms for RETRIEVAL purposes
|
|
459
|
+
6. Verify entities appear in paper (no hallucination)
|
|
460
|
+
7. When uncertain, INCLUDE IT
|
|
461
|
+
8. Ignore [HINT_BASELINE:...] markers in output
|
|
462
|
+
|
|
463
|
+
Return JSON only:"""
|
|
464
|
+
|
|
465
|
+
return system, user
|
|
466
|
+
|
|
467
|
+
|
|
468
|
+
# ================= VALIDATION & PARSING (COMBINED) =================
|
|
469
|
+
|
|
470
|
+
def validate_and_parse_main(response: str, info_dict: dict = None) -> Tuple[bool, dict]:
|
|
471
|
+
"""
|
|
472
|
+
Validate and parse main extraction response.
|
|
473
|
+
|
|
474
|
+
This function combines validation and parsing - the second return value
|
|
475
|
+
is the parsed result for use in aggregation.
|
|
476
|
+
|
|
477
|
+
Args:
|
|
478
|
+
response: LLM response string
|
|
479
|
+
info_dict: Optional dict with 'node_id' and 'title' (original title from markdown)
|
|
480
|
+
|
|
481
|
+
Returns:
|
|
482
|
+
Tuple of (is_valid, parsed_result_or_response)
|
|
483
|
+
- If valid: (True, parsed dict with node_id and result)
|
|
484
|
+
- If invalid: raises ValueError
|
|
485
|
+
"""
|
|
486
|
+
if not response:
|
|
487
|
+
raise ValueError("Empty response")
|
|
488
|
+
|
|
489
|
+
parsed = extract_json(response)
|
|
490
|
+
|
|
491
|
+
if not isinstance(parsed, dict):
|
|
492
|
+
raise ValueError("Response is not a JSON object")
|
|
493
|
+
|
|
494
|
+
# Check required top-level keys
|
|
495
|
+
if 'metadata' not in parsed:
|
|
496
|
+
raise ValueError("Missing required key: metadata")
|
|
497
|
+
|
|
498
|
+
# Extract core names for baseline extraction
|
|
499
|
+
core_contributions = parsed.get("core_contributions", [])
|
|
500
|
+
core_names = [c.get("name") for c in core_contributions if c.get("name")]
|
|
501
|
+
|
|
502
|
+
# Extract original title from info_dict for fallback (info_dict contains the extracted title from markdown)
|
|
503
|
+
original_title = None
|
|
504
|
+
if info_dict:
|
|
505
|
+
original_title = info_dict.get('title')
|
|
506
|
+
|
|
507
|
+
result = {
|
|
508
|
+
'node_id': info_dict.get('node_id') if info_dict else None,
|
|
509
|
+
'result': parsed,
|
|
510
|
+
'core_names': core_names,
|
|
511
|
+
'original_title': original_title
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
return True, result
|
|
515
|
+
|
|
516
|
+
|
|
517
|
+
def validate_and_parse_baseline(response: str, info_dict: dict = None) -> Tuple[bool, dict]:
|
|
518
|
+
"""
|
|
519
|
+
Validate and parse baseline extraction response.
|
|
520
|
+
|
|
521
|
+
This function combines validation and parsing - the second return value
|
|
522
|
+
is the parsed result for use in aggregation.
|
|
523
|
+
|
|
524
|
+
Args:
|
|
525
|
+
response: LLM response string
|
|
526
|
+
info_dict: Optional dict with 'node_id' and 'core_names'
|
|
527
|
+
|
|
528
|
+
Returns:
|
|
529
|
+
Tuple of (is_valid, parsed_result_or_response)
|
|
530
|
+
- If valid: (True, parsed dict with node_id and result)
|
|
531
|
+
- If invalid: raises ValueError
|
|
532
|
+
"""
|
|
533
|
+
if not response:
|
|
534
|
+
raise ValueError("Empty response")
|
|
535
|
+
|
|
536
|
+
parsed = extract_json(response)
|
|
537
|
+
|
|
538
|
+
if not isinstance(parsed, dict):
|
|
539
|
+
raise ValueError("Response is not a JSON object")
|
|
540
|
+
|
|
541
|
+
# Check required top-level keys
|
|
542
|
+
if 'baselines' not in parsed and 'datasets' not in parsed:
|
|
543
|
+
raise ValueError("Missing required keys: baselines or datasets")
|
|
544
|
+
|
|
545
|
+
result = {
|
|
546
|
+
'node_id': info_dict.get('node_id') if info_dict else None,
|
|
547
|
+
'result': parsed,
|
|
548
|
+
'core_names': info_dict.get('core_names', []) if info_dict else []
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
return True, result
|
|
552
|
+
|
|
553
|
+
|
|
554
|
+
# ================= RESULT AGGREGATOR =================
|
|
555
|
+
|
|
556
|
+
def aggregate_results(
|
|
557
|
+
main_results: List[dict],
|
|
558
|
+
baseline_results: List[dict],
|
|
559
|
+
source_info: Dict[str, dict]
|
|
560
|
+
) -> List[dict]:
|
|
561
|
+
"""Aggregate main and baseline results into final output."""
|
|
562
|
+
main_by_paper = {r['node_id']: r for r in main_results if r}
|
|
563
|
+
baseline_by_paper = {r['node_id']: r for r in (baseline_results or []) if r}
|
|
564
|
+
|
|
565
|
+
aggregated = []
|
|
566
|
+
for node_id in main_by_paper:
|
|
567
|
+
main_res = main_by_paper[node_id]
|
|
568
|
+
baseline_res = baseline_by_paper.get(node_id, {})
|
|
569
|
+
info = source_info.get(node_id, {})
|
|
570
|
+
|
|
571
|
+
result = main_res['result']
|
|
572
|
+
core_contributions = result.get("core_contributions", [])
|
|
573
|
+
core_names = main_res.get('core_names', [])
|
|
574
|
+
|
|
575
|
+
meta_info = result.get("metadata", {})
|
|
576
|
+
# Use LLM's title if available, otherwise use original_title from extraction
|
|
577
|
+
official_title = meta_info.get('title', 'Unknown')
|
|
578
|
+
if official_title == 'Unknown' or not official_title:
|
|
579
|
+
# Fallback to original title extracted from markdown
|
|
580
|
+
original_title = main_res.get('original_title')
|
|
581
|
+
if original_title and original_title != 'Unknown Title':
|
|
582
|
+
official_title = original_title
|
|
583
|
+
|
|
584
|
+
# Build self-reference set
|
|
585
|
+
self_names = {official_title.lower(), "ours", "proposed", "method", "model", "framework", "this work"}
|
|
586
|
+
for c in core_contributions:
|
|
587
|
+
if c.get("name"): self_names.add(c.get("name").lower())
|
|
588
|
+
if c.get("acronym"): self_names.add(c.get("acronym").lower())
|
|
589
|
+
|
|
590
|
+
# Filter components
|
|
591
|
+
valid_components = []
|
|
592
|
+
for comp in result.get("components", []):
|
|
593
|
+
c_name = comp.get("name", "").strip()
|
|
594
|
+
if not c_name or c_name.lower() in self_names:
|
|
595
|
+
continue
|
|
596
|
+
if any(c_name.lower() == cn.lower() for cn in core_names):
|
|
597
|
+
continue
|
|
598
|
+
related = comp.get("related_to_core")
|
|
599
|
+
if related not in core_names and len(core_names) == 1:
|
|
600
|
+
comp["related_to_core"] = core_names[0]
|
|
601
|
+
valid_components.append(comp)
|
|
602
|
+
|
|
603
|
+
# Filter baselines
|
|
604
|
+
valid_baselines = []
|
|
605
|
+
graph_data = baseline_res.get('result', {})
|
|
606
|
+
for item in graph_data.get("baselines", []):
|
|
607
|
+
name = item.get("name", "").strip()
|
|
608
|
+
if not name or name.lower() in self_names:
|
|
609
|
+
continue
|
|
610
|
+
related = item.get("related_to_core")
|
|
611
|
+
if related not in core_names and len(core_names) >= 1:
|
|
612
|
+
item["related_to_core"] = core_names[0]
|
|
613
|
+
if "keywords" in item:
|
|
614
|
+
item["keywords"] = [k for k in item["keywords"] if k.lower() not in METRIC_BLACKLIST]
|
|
615
|
+
valid_baselines.append(item)
|
|
616
|
+
|
|
617
|
+
# Filter datasets
|
|
618
|
+
valid_datasets = []
|
|
619
|
+
for ds in graph_data.get("datasets", []):
|
|
620
|
+
name = ds.get("name", "").strip()
|
|
621
|
+
if not name:
|
|
622
|
+
continue
|
|
623
|
+
related = ds.get("related_to_core")
|
|
624
|
+
if related not in core_names and len(core_names) >= 1:
|
|
625
|
+
ds["related_to_core"] = core_names[0]
|
|
626
|
+
valid_datasets.append(ds)
|
|
627
|
+
|
|
628
|
+
final_output = {
|
|
629
|
+
"node_id": node_id,
|
|
630
|
+
"source_venue": info.get("source_venue", "Unknown"),
|
|
631
|
+
"pub_year": info.get("pub_year", "2024"),
|
|
632
|
+
"metadata": {
|
|
633
|
+
"title": official_title,
|
|
634
|
+
"domain": meta_info.get("domain", "Others"),
|
|
635
|
+
"paper_type": meta_info.get("paper_type", "Others"),
|
|
636
|
+
"structured_summary": meta_info.get("structured_summary", {}),
|
|
637
|
+
"code_url": meta_info.get("code_url")
|
|
638
|
+
},
|
|
639
|
+
"ideation_resource": {
|
|
640
|
+
"problems": result.get("problems", []),
|
|
641
|
+
"core_contributions": core_contributions,
|
|
642
|
+
"core_relations": result.get("core_relations", []),
|
|
643
|
+
"components": valid_components,
|
|
644
|
+
"innovations": result.get("innovations", []),
|
|
645
|
+
"limitations": result.get("limitations", []),
|
|
646
|
+
"future_work": result.get("future_work", [])
|
|
647
|
+
},
|
|
648
|
+
"graph_data": {
|
|
649
|
+
"baselines": valid_baselines,
|
|
650
|
+
"datasets": valid_datasets
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
aggregated.append(final_output)
|
|
654
|
+
|
|
655
|
+
return aggregated
|
|
656
|
+
|
|
657
|
+
|
|
658
|
+
# ================= MAIN PIPELINE FUNCTION =================
|
|
659
|
+
|
|
660
|
+
def extract_paper_info_batch(
|
|
661
|
+
papers: Dict[str, str],
|
|
662
|
+
chat_agent,
|
|
663
|
+
source_info: Dict[str, str] = None,
|
|
664
|
+
temperature: float = 0.05,
|
|
665
|
+
max_retry: int = 3,
|
|
666
|
+
) -> List[dict]:
|
|
667
|
+
"""
|
|
668
|
+
Extract paper information using ChatAgent with retry.
|
|
669
|
+
|
|
670
|
+
Args:
|
|
671
|
+
papers: Dict mapping paper_id -> markdown_text
|
|
672
|
+
chat_agent: ChatAgent instance with batch_remote_chat_with_retry method
|
|
673
|
+
source_info: Optional dict mapping paper_id -> {source_venue, pub_year}
|
|
674
|
+
temperature: LLM temperature
|
|
675
|
+
max_retry: Max retry attempts per prompt
|
|
676
|
+
|
|
677
|
+
Returns:
|
|
678
|
+
List of extraction results
|
|
679
|
+
"""
|
|
680
|
+
if source_info is None:
|
|
681
|
+
source_info = {}
|
|
682
|
+
|
|
683
|
+
paper_ids = list(papers.keys())
|
|
684
|
+
markdowns = list(papers.values())
|
|
685
|
+
|
|
686
|
+
# ===== Step 1: Main Extraction =====
|
|
687
|
+
main_prompts = []
|
|
688
|
+
main_metadata = []
|
|
689
|
+
|
|
690
|
+
for paper_id, markdown in zip(paper_ids, markdowns):
|
|
691
|
+
# Extract title from markdown
|
|
692
|
+
title = "Unknown Title"
|
|
693
|
+
for line in markdown.split('\n')[:20]:
|
|
694
|
+
match = re.match(r'^#\s+(.+)$', line.strip())
|
|
695
|
+
if match:
|
|
696
|
+
title = clean_title_latex(match.group(1))
|
|
697
|
+
break
|
|
698
|
+
|
|
699
|
+
regex_candidates = extract_regex_candidates(markdown)
|
|
700
|
+
system, user = build_main_extraction_prompt(markdown, title, regex_candidates)
|
|
701
|
+
|
|
702
|
+
# Combine system + user for the prompt
|
|
703
|
+
full_prompt = f"{system}\n\n{user}"
|
|
704
|
+
main_prompts.append(full_prompt)
|
|
705
|
+
main_metadata.append({
|
|
706
|
+
'paper_id': paper_id,
|
|
707
|
+
'title': title,
|
|
708
|
+
'regex_candidates': regex_candidates
|
|
709
|
+
})
|
|
710
|
+
|
|
711
|
+
# Call with retry and validation - info_dict contains paper_id for later aggregation
|
|
712
|
+
main_responses = chat_agent.batch_remote_chat_with_retry(
|
|
713
|
+
main_prompts,
|
|
714
|
+
validate_fn=validate_and_parse_main,
|
|
715
|
+
max_retry=max_retry,
|
|
716
|
+
desc="Main extraction",
|
|
717
|
+
temperature=temperature,
|
|
718
|
+
info_dict={'metadata': main_metadata} # Pass metadata for aggregation
|
|
719
|
+
)
|
|
720
|
+
|
|
721
|
+
# main_responses are already parsed results from validate_and_parse_main
|
|
722
|
+
main_results = main_responses
|
|
723
|
+
|
|
724
|
+
# Build core names map for baseline extraction
|
|
725
|
+
core_names_map = {}
|
|
726
|
+
for res in main_results:
|
|
727
|
+
if res:
|
|
728
|
+
core_names_map[res['node_id']] = res.get('core_names', [])
|
|
729
|
+
|
|
730
|
+
# ===== Step 2: Baseline Extraction =====
|
|
731
|
+
baseline_prompts = []
|
|
732
|
+
baseline_metadata = []
|
|
733
|
+
|
|
734
|
+
for paper_id, markdown in zip(paper_ids, markdowns):
|
|
735
|
+
core_names = core_names_map.get(paper_id, [])
|
|
736
|
+
regex_candidates = extract_regex_candidates(markdown)
|
|
737
|
+
system, user = build_baseline_extraction_prompt(markdown, core_names, regex_candidates)
|
|
738
|
+
|
|
739
|
+
full_prompt = f"{system}\n\n{user}"
|
|
740
|
+
baseline_prompts.append(full_prompt)
|
|
741
|
+
baseline_metadata.append({
|
|
742
|
+
'paper_id': paper_id,
|
|
743
|
+
'core_names': core_names
|
|
744
|
+
})
|
|
745
|
+
|
|
746
|
+
# Call with retry and validation
|
|
747
|
+
baseline_responses = chat_agent.batch_remote_chat_with_retry(
|
|
748
|
+
baseline_prompts,
|
|
749
|
+
validate_fn=validate_and_parse_baseline,
|
|
750
|
+
max_retry=max_retry,
|
|
751
|
+
desc="Baseline extraction",
|
|
752
|
+
temperature=temperature,
|
|
753
|
+
info_dict={'metadata': baseline_metadata}
|
|
754
|
+
)
|
|
755
|
+
|
|
756
|
+
# baseline_responses are already parsed results from validate_and_parse_baseline
|
|
757
|
+
baseline_results = baseline_responses
|
|
758
|
+
|
|
759
|
+
# ===== Step 3: Aggregate =====
|
|
760
|
+
return aggregate_results(main_results, baseline_results, source_info)
|
|
761
|
+
|
|
762
|
+
|
|
763
|
+
def format_extraction_result(result: dict) -> str:
|
|
764
|
+
"""Format extraction result into readable keynote string."""
|
|
765
|
+
if not result:
|
|
766
|
+
return "No details found."
|
|
767
|
+
|
|
768
|
+
meta = result.get('metadata', {})
|
|
769
|
+
structured_summary = meta.get('structured_summary', {})
|
|
770
|
+
|
|
771
|
+
formatted = f"Paper Title: {meta.get('title', 'N/A')}\n"
|
|
772
|
+
formatted += f"Paper Type: {meta.get('paper_type', 'N/A')}\n"
|
|
773
|
+
formatted += f"Domain: {meta.get('domain', 'N/A')}\n"
|
|
774
|
+
formatted += f"Summary (Background): {structured_summary.get('background', 'N/A')}\n"
|
|
775
|
+
formatted += f"Summary (Method): {structured_summary.get('method', 'N/A')}\n"
|
|
776
|
+
formatted += f"Summary (Result): {structured_summary.get('result', 'N/A')}\n"
|
|
777
|
+
|
|
778
|
+
ideation = result.get('ideation_resource', {})
|
|
779
|
+
cores = ideation.get('core_contributions', [])
|
|
780
|
+
if cores:
|
|
781
|
+
formatted += f"\nCore Contributions:\n"
|
|
782
|
+
for core in cores:
|
|
783
|
+
formatted += f" - {core.get('name', 'N/A')}: {core.get('summary', 'N/A')}\n"
|
|
784
|
+
formatted += f" Insight: {core.get('insight', 'N/A')}\n"
|
|
785
|
+
|
|
786
|
+
# Add Components section
|
|
787
|
+
components = ideation.get('components', [])
|
|
788
|
+
if components:
|
|
789
|
+
formatted += f"\nComponents:\n"
|
|
790
|
+
for comp in components:
|
|
791
|
+
related_to_core = comp.get('related_to_core', 'N/A')
|
|
792
|
+
formatted += f" - {comp.get('name', 'N/A')} (Part of: {related_to_core})\n"
|
|
793
|
+
formatted += f" Summary: {comp.get('summary', 'N/A')}\n"
|
|
794
|
+
formatted += f" Insight: {comp.get('insight', 'N/A')}\n"
|
|
795
|
+
|
|
796
|
+
all_keywords = []
|
|
797
|
+
for core in cores:
|
|
798
|
+
all_keywords.extend(core.get('keywords', []))
|
|
799
|
+
for comp in components:
|
|
800
|
+
all_keywords.extend(comp.get('keywords', []))
|
|
801
|
+
if all_keywords:
|
|
802
|
+
formatted += f"\nKeywords: {', '.join(all_keywords[:15])}\n"
|
|
803
|
+
|
|
804
|
+
return formatted
|
|
805
|
+
|
|
806
|
+
|
|
807
|
+
# ================= WRAPPER FUNCTIONS FOR COMPATIBILITY =================
|
|
808
|
+
|
|
809
|
+
def build_main_extraction_prompts(papers: Dict[str, str]) -> List[tuple]:
|
|
810
|
+
"""
|
|
811
|
+
Build main extraction prompts for multiple papers.
|
|
812
|
+
Returns list of (full_prompt, paper_id, metadata_dict)
|
|
813
|
+
"""
|
|
814
|
+
results = []
|
|
815
|
+
for paper_id, markdown in papers.items():
|
|
816
|
+
# Extract title from markdown
|
|
817
|
+
title = "Unknown Title"
|
|
818
|
+
for line in markdown.split('\n')[:20]:
|
|
819
|
+
match = re.match(r'^#\s+(.+)$', line.strip())
|
|
820
|
+
if match:
|
|
821
|
+
title = clean_title_latex(match.group(1))
|
|
822
|
+
break
|
|
823
|
+
|
|
824
|
+
regex_candidates = extract_regex_candidates(markdown)
|
|
825
|
+
system, user = build_main_extraction_prompt(markdown, title, regex_candidates)
|
|
826
|
+
full_prompt = f"{system}\n\n{user}"
|
|
827
|
+
|
|
828
|
+
results.append((full_prompt, paper_id, {'title': title, 'regex_candidates': regex_candidates}))
|
|
829
|
+
|
|
830
|
+
return results
|
|
831
|
+
|
|
832
|
+
|
|
833
|
+
def build_baseline_extraction_prompts(papers: Dict[str, str], core_names_map: Dict[str, List[str]]) -> List[tuple]:
|
|
834
|
+
"""
|
|
835
|
+
Build baseline extraction prompts for multiple papers.
|
|
836
|
+
Returns list of (full_prompt, paper_id, metadata_dict)
|
|
837
|
+
"""
|
|
838
|
+
results = []
|
|
839
|
+
for paper_id, markdown in papers.items():
|
|
840
|
+
core_names = core_names_map.get(paper_id, [])
|
|
841
|
+
regex_candidates = extract_regex_candidates(markdown)
|
|
842
|
+
system, user = build_baseline_extraction_prompt(markdown, core_names, regex_candidates)
|
|
843
|
+
full_prompt = f"{system}\n\n{user}"
|
|
844
|
+
|
|
845
|
+
results.append((full_prompt, paper_id, {'core_names': core_names}))
|
|
846
|
+
|
|
847
|
+
return results
|
|
848
|
+
|
|
849
|
+
|
|
850
|
+
def aggregate_extraction_results(
|
|
851
|
+
main_results: List[dict],
|
|
852
|
+
baseline_results: List[dict],
|
|
853
|
+
source_info: Dict[str, dict]
|
|
854
|
+
) -> List[dict]:
|
|
855
|
+
"""Wrapper for aggregate_results for compatibility."""
|
|
856
|
+
return aggregate_results(main_results, baseline_results, source_info)
|