Create a project from a topic string. Modes: - "lab": Multi-angle parallel research (default). If no angles provided, uses 3 default perspectives. Each agent gets a specialized role prompt. - "reproduce": Single-agent focused pipeline for paper reproduction.
(
state: BridgeState, topic: str, project_id: str = "",
mode: str = "lab",
research_angles: list[str] | None = None,
reference_papers: list[str] | None = None,
reference_uploads: list[dict[str, str]] | None = None,
path_overrides: dict[str, str] | None = None,
)
| 1930 | datasets_dir=_po.get("datasets_dir", ""), |
| 1931 | checkpoints_dir=_po.get("checkpoints_dir", ""), |
| 1932 | ) |
| 1933 | except Exception as e: |
| 1934 | messages.append(msg_log(sys_agent, f"配置生成失败: {e}", "error")) |
| 1935 | return messages |
| 1936 | messages.append(msg_log(sys_agent, f"复现模式: 项目 [{base_id}] 单 Agent 全流程启动", "success")) |
| 1937 | messages.extend(submit_new_project(state, base_id, config_path, topic.strip(), mode="reproduce")) |
| 1938 | return messages |
| 1939 | |
| 1940 | # ── Lab mode: parallel research (ONE project, N agents — or 1 agent if single direction) ── |
| 1941 | angles: list[dict[str, str]] |
| 1942 | if research_angles and len(research_angles) >= 1: |
| 1943 | angles = [ |
| 1944 | {"name": a.strip(), "prompt": _build_role_prompt(a.strip(), topic.strip())} |
| 1945 | for a in research_angles if a.strip() |
| 1946 | ] |
| 1947 | if not research_angles or not angles: |
| 1948 | angles = DEFAULT_LAB_ANGLES |
| 1949 | |
| 1950 | # Deduplicate project id |
| 1951 | existing = state.projects_dir() / base_id |
| 1952 | if existing.exists(): |
| 1953 | base_id = f"{base_id}-{_uid()[:4]}" |
| 1954 | |
| 1955 | project_dir = state.projects_dir() / base_id |
| 1956 | project_dir.mkdir(parents=True, exist_ok=True) |
| 1957 | |
| 1958 | _po = path_overrides or {} |
| 1959 | try: |
| 1960 | project_config_path = _generate_config_from_template( |
| 1961 | state, base_id, topic.strip(), |
| 1962 | reference_papers=reference_papers, |
| 1963 | codebases_dir=_po.get("codebases_dir", ""), |
| 1964 | datasets_dir=_po.get("datasets_dir", ""), |
| 1965 | checkpoints_dir=_po.get("checkpoints_dir", ""), |
| 1966 | ) |
| 1967 | except Exception as e: |
| 1968 | messages.append(msg_log(sys_agent, f"配置生成失败: {e}", "error")) |
| 1969 | return messages |
| 1970 | |
| 1971 | _save_project_meta(str(project_dir), base_id, project_config_path, topic.strip(), mode="lab") |
| 1972 | |
| 1973 | messages.append(msg_log( |
| 1974 | sys_agent, |
| 1975 | f"Lab 模式: 项目 [{base_id}] — {len(angles)} 个方向并行调研", |
| 1976 | "info", |
| 1977 | )) |
| 1978 | |
| 1979 | task_count = 0 |
| 1980 | for i, angle in enumerate(angles): |
| 1981 | name = angle["name"] |
| 1982 | role_prompt = angle["prompt"] |
| 1983 | slug = _slugify(name, 20) |
| 1984 | |
| 1985 | # Each direction gets its own run sub-directory within the project |
| 1986 | run_dir = str(project_dir / f"run-{slug}") |
| 1987 | os.makedirs(run_dir, exist_ok=True) |
| 1988 | |
| 1989 | _po = path_overrides or {} |
no test coverage detected