Spaces:
Running
Running
U1-R2B Research Design UI + Manual Override
#127
by GuXiaopeng - opened
- app.py +48 -29
- core/advanced_method_registry.py +35 -53
- i18n.py +58 -54
app.py
CHANGED
|
@@ -306,6 +306,8 @@ for key, default in {
|
|
| 306 |
"sp_completed_download_scroll_task_id": "",
|
| 307 |
"sp_method_confirmation": "",
|
| 308 |
"sp_method_confirmation_signature": "",
|
|
|
|
|
|
|
| 309 |
"sp_material_document_use": "reference",
|
| 310 |
}.items():
|
| 311 |
if key not in st.session_state:
|
|
@@ -506,7 +508,6 @@ def _method_intent_signature() -> str:
|
|
| 506 |
payload = {
|
| 507 |
"topic": str(st.session_state.get("sp_topic") or DEFAULT_TOPIC),
|
| 508 |
"keywords": str(st.session_state.get("sp_keywords") or DEFAULT_KEYWORDS),
|
| 509 |
-
"materials": _uploaded_material_descriptors(),
|
| 510 |
}
|
| 511 |
return hashlib.sha256(
|
| 512 |
json.dumps(payload, ensure_ascii=False, sort_keys=True, separators=(",", ":")).encode("utf-8")
|
|
@@ -776,8 +777,9 @@ def _process_pending_launch(lang_code: str) -> None:
|
|
| 776 |
idempotency_key = str(pending.get("idempotency_key") or "").strip()
|
| 777 |
pending_signature = str(pending.get("method_intent_signature") or "").strip()
|
| 778 |
|
| 779 |
-
# U1-
|
| 780 |
-
# creation so a stale rerun or modified session state cannot bypass
|
|
|
|
| 781 |
preflight, current_signature = _current_method_preflight(
|
| 782 |
confirmed_method_family=pending_family or None
|
| 783 |
)
|
|
@@ -797,7 +799,7 @@ def _process_pending_launch(lang_code: str) -> None:
|
|
| 797 |
method_label = tr(lang_code, f"method_{resolved_family}")
|
| 798 |
st.warning(tr(lang_code, "method_not_supported", method=method_label))
|
| 799 |
else:
|
| 800 |
-
st.warning(tr(lang_code, "
|
| 801 |
return
|
| 802 |
|
| 803 |
projection = get_product_ui_projection()
|
|
@@ -1504,30 +1506,48 @@ def render_workspace_controls(user):
|
|
| 1504 |
}
|
| 1505 |
method_signature = ""
|
| 1506 |
else:
|
| 1507 |
-
|
| 1508 |
-
|
| 1509 |
-
|
| 1510 |
-
|
| 1511 |
-
|
| 1512 |
-
|
| 1513 |
-
|
| 1514 |
-
|
| 1515 |
-
|
| 1516 |
-
|
| 1517 |
-
|
| 1518 |
-
|
| 1519 |
-
|
| 1520 |
-
|
| 1521 |
-
|
| 1522 |
-
|
| 1523 |
-
|
| 1524 |
-
|
| 1525 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1526 |
else:
|
| 1527 |
-
# Explicit Title/Keyword cues are authoritative; stale confirmations
|
| 1528 |
-
# from a previous ambiguous intent cannot override them.
|
| 1529 |
st.session_state["sp_method_confirmation"] = ""
|
| 1530 |
st.session_state["sp_method_confirmation_signature"] = ""
|
|
|
|
| 1531 |
|
| 1532 |
method_family = str(preflight.get("method_family") or "undetermined").strip().casefold()
|
| 1533 |
method_label = (
|
|
@@ -1535,14 +1555,13 @@ def render_workspace_controls(user):
|
|
| 1535 |
if method_family in METHOD_FAMILIES
|
| 1536 |
else tr(lang_code, "method_undetermined")
|
| 1537 |
)
|
| 1538 |
-
|
|
|
|
| 1539 |
st.caption(tr(lang_code, "method_detection_explanation"))
|
| 1540 |
|
| 1541 |
block_reason = str(preflight.get("block_reason") or "")
|
| 1542 |
if block_reason == "method_capability_blocked":
|
| 1543 |
st.warning(tr(lang_code, "method_not_supported", method=method_label))
|
| 1544 |
-
elif block_reason == "method_confirmation_required":
|
| 1545 |
-
st.warning(tr(lang_code, "method_confirmation_required"))
|
| 1546 |
elif not active:
|
| 1547 |
st.info(tr(lang_code, "method_supported", method=method_label))
|
| 1548 |
|
|
@@ -1639,7 +1658,7 @@ def render_workspace_controls(user):
|
|
| 1639 |
if reason == "method_capability_blocked":
|
| 1640 |
st.warning(tr(lang_code, "method_not_supported", method=method_label))
|
| 1641 |
else:
|
| 1642 |
-
st.warning(tr(lang_code, "
|
| 1643 |
else:
|
| 1644 |
resolved_family = str(click_preflight.get("method_family") or "").strip().casefold()
|
| 1645 |
resolved_mode = str(click_preflight.get("legacy_policy_lane") or "").strip().lower()
|
|
|
|
| 306 |
"sp_completed_download_scroll_task_id": "",
|
| 307 |
"sp_method_confirmation": "",
|
| 308 |
"sp_method_confirmation_signature": "",
|
| 309 |
+
"sp_method_selector": "qualitative",
|
| 310 |
+
"sp_method_selector_signature": "",
|
| 311 |
"sp_material_document_use": "reference",
|
| 312 |
}.items():
|
| 313 |
if key not in st.session_state:
|
|
|
|
| 508 |
payload = {
|
| 509 |
"topic": str(st.session_state.get("sp_topic") or DEFAULT_TOPIC),
|
| 510 |
"keywords": str(st.session_state.get("sp_keywords") or DEFAULT_KEYWORDS),
|
|
|
|
| 511 |
}
|
| 512 |
return hashlib.sha256(
|
| 513 |
json.dumps(payload, ensure_ascii=False, sort_keys=True, separators=(",", ":")).encode("utf-8")
|
|
|
|
| 777 |
idempotency_key = str(pending.get("idempotency_key") or "").strip()
|
| 778 |
pending_signature = str(pending.get("method_intent_signature") or "").strip()
|
| 779 |
|
| 780 |
+
# U1-R2B repeats the capability preflight immediately before any task/quota
|
| 781 |
+
# creation so a stale rerun or modified session state cannot bypass a
|
| 782 |
+
# manually adjusted or auto/default research design.
|
| 783 |
preflight, current_signature = _current_method_preflight(
|
| 784 |
confirmed_method_family=pending_family or None
|
| 785 |
)
|
|
|
|
| 799 |
method_label = tr(lang_code, f"method_{resolved_family}")
|
| 800 |
st.warning(tr(lang_code, "method_not_supported", method=method_label))
|
| 801 |
else:
|
| 802 |
+
st.warning(tr(lang_code, "method_resolution_invalid"))
|
| 803 |
return
|
| 804 |
|
| 805 |
projection = get_product_ui_projection()
|
|
|
|
| 1506 |
}
|
| 1507 |
method_signature = ""
|
| 1508 |
else:
|
| 1509 |
+
# U1-R2B: Title + Keywords determine the automatic design. If no design
|
| 1510 |
+
# cue is present, the resolver defaults to qualitative. The selector is
|
| 1511 |
+
# always visible for a new task and may override the automatic/default
|
| 1512 |
+
# choice, but the capability gate still runs afterwards.
|
| 1513 |
+
auto_preflight, method_signature = _current_method_preflight(confirmed_method_family="")
|
| 1514 |
+
auto_family = str(auto_preflight.get("method_family") or "qualitative").strip().casefold()
|
| 1515 |
+
if auto_family not in METHOD_FAMILIES:
|
| 1516 |
+
auto_family = "qualitative"
|
| 1517 |
+
|
| 1518 |
+
stored = str(st.session_state.get("sp_method_confirmation") or "").strip().casefold()
|
| 1519 |
+
stored_sig = str(st.session_state.get("sp_method_confirmation_signature") or "").strip()
|
| 1520 |
+
selected_default = stored if stored_sig == method_signature and stored in METHOD_FAMILIES else auto_family
|
| 1521 |
+
|
| 1522 |
+
# A changed Title/Keywords signature invalidates a previous manual
|
| 1523 |
+
# override and resets the visible selector to the fresh auto/default
|
| 1524 |
+
# result. This prevents stale method choices leaking across topics.
|
| 1525 |
+
selector_sig = str(st.session_state.get("sp_method_selector_signature") or "").strip()
|
| 1526 |
+
if selector_sig != method_signature:
|
| 1527 |
+
st.session_state["sp_method_confirmation"] = ""
|
| 1528 |
+
st.session_state["sp_method_confirmation_signature"] = ""
|
| 1529 |
+
st.session_state["sp_method_selector"] = auto_family
|
| 1530 |
+
st.session_state["sp_method_selector_signature"] = method_signature
|
| 1531 |
+
selected_default = auto_family
|
| 1532 |
+
elif str(st.session_state.get("sp_method_selector") or "").strip().casefold() not in METHOD_FAMILIES:
|
| 1533 |
+
st.session_state["sp_method_selector"] = selected_default
|
| 1534 |
+
|
| 1535 |
+
selected = st.selectbox(
|
| 1536 |
+
tr(lang_code, "detected_method_label"),
|
| 1537 |
+
list(METHOD_FAMILIES),
|
| 1538 |
+
index=list(METHOD_FAMILIES).index(selected_default),
|
| 1539 |
+
format_func=lambda family: tr(lang_code, f"method_{family}"),
|
| 1540 |
+
key="sp_method_selector",
|
| 1541 |
+
disabled=active,
|
| 1542 |
+
)
|
| 1543 |
+
selected = str(selected or auto_family).strip().casefold()
|
| 1544 |
+
if selected != auto_family:
|
| 1545 |
+
st.session_state["sp_method_confirmation"] = selected
|
| 1546 |
+
st.session_state["sp_method_confirmation_signature"] = method_signature
|
| 1547 |
else:
|
|
|
|
|
|
|
| 1548 |
st.session_state["sp_method_confirmation"] = ""
|
| 1549 |
st.session_state["sp_method_confirmation_signature"] = ""
|
| 1550 |
+
preflight, method_signature = _current_method_preflight(confirmed_method_family=selected)
|
| 1551 |
|
| 1552 |
method_family = str(preflight.get("method_family") or "undetermined").strip().casefold()
|
| 1553 |
method_label = (
|
|
|
|
| 1555 |
if method_family in METHOD_FAMILIES
|
| 1556 |
else tr(lang_code, "method_undetermined")
|
| 1557 |
)
|
| 1558 |
+
if active:
|
| 1559 |
+
st.markdown(f"**{tr(lang_code, 'detected_method_label')}:** {method_label}")
|
| 1560 |
st.caption(tr(lang_code, "method_detection_explanation"))
|
| 1561 |
|
| 1562 |
block_reason = str(preflight.get("block_reason") or "")
|
| 1563 |
if block_reason == "method_capability_blocked":
|
| 1564 |
st.warning(tr(lang_code, "method_not_supported", method=method_label))
|
|
|
|
|
|
|
| 1565 |
elif not active:
|
| 1566 |
st.info(tr(lang_code, "method_supported", method=method_label))
|
| 1567 |
|
|
|
|
| 1658 |
if reason == "method_capability_blocked":
|
| 1659 |
st.warning(tr(lang_code, "method_not_supported", method=method_label))
|
| 1660 |
else:
|
| 1661 |
+
st.warning(tr(lang_code, "method_resolution_invalid"))
|
| 1662 |
else:
|
| 1663 |
resolved_family = str(click_preflight.get("method_family") or "").strip().casefold()
|
| 1664 |
resolved_mode = str(click_preflight.get("legacy_policy_lane") or "").strip().lower()
|
core/advanced_method_registry.py
CHANGED
|
@@ -1,10 +1,13 @@
|
|
| 1 |
# -*- coding: utf-8 -*-
|
| 2 |
-
"""Deterministic
|
| 3 |
|
| 4 |
-
U1-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
|
|
|
|
|
|
|
|
|
| 8 |
"""
|
| 9 |
from __future__ import annotations
|
| 10 |
|
|
@@ -12,7 +15,7 @@ import os
|
|
| 12 |
import re
|
| 13 |
from typing import Any, Iterable
|
| 14 |
|
| 15 |
-
METHOD_RESOLVER_VERSION = "smartpaper-auto-method-resolver-
|
| 16 |
METHOD_CAPABILITY_REGISTRY_VERSION = "smartpaper-method-capability-registry-v2"
|
| 17 |
|
| 18 |
METHOD_FAMILIES = (
|
|
@@ -197,11 +200,12 @@ def resolve_method_family(
|
|
| 197 |
*,
|
| 198 |
materials: Iterable[Any] | None = None,
|
| 199 |
) -> dict[str, Any]:
|
| 200 |
-
"""Resolve
|
| 201 |
|
| 202 |
-
|
| 203 |
-
|
| 204 |
-
|
|
|
|
| 205 |
"""
|
| 206 |
source_title = _normalized_text(title)
|
| 207 |
source_keywords = _keyword_items(keywords)
|
|
@@ -217,41 +221,28 @@ def resolve_method_family(
|
|
| 217 |
chosen = family
|
| 218 |
|
| 219 |
descriptors = _material_descriptors(materials)
|
| 220 |
-
material_hits: list[str] = []
|
| 221 |
-
for descriptor in descriptors:
|
| 222 |
-
name = descriptor.get("name") or ""
|
| 223 |
-
for family, patterns in _MATERIAL_NAME_PATTERNS:
|
| 224 |
-
if any(re.search(pattern, name, flags=re.I | re.UNICODE) for pattern in patterns):
|
| 225 |
-
if family not in material_hits:
|
| 226 |
-
material_hits.append(family)
|
| 227 |
|
| 228 |
-
|
| 229 |
-
# no explicit cue, one unique material hint is useful but remains ambiguous
|
| 230 |
-
# until future U1 benchmarks justify auto-acceptance.
|
| 231 |
-
confidence = "HIGH_CONFIDENCE" if chosen else "AMBIGUOUS"
|
| 232 |
reason_codes: list[str] = []
|
| 233 |
if chosen:
|
| 234 |
reason_codes.append("explicit_title_keyword_method_cue")
|
| 235 |
conflicting = [row["method_family"] for row in hits if row["method_family"] != chosen]
|
| 236 |
if conflicting:
|
| 237 |
reason_codes.append("lower_priority_method_cues_present")
|
| 238 |
-
elif len(material_hits) == 1:
|
| 239 |
-
chosen = material_hits[0]
|
| 240 |
-
reason_codes.append("material_filename_method_hint_only")
|
| 241 |
-
elif len(material_hits) > 1:
|
| 242 |
-
reason_codes.append("conflicting_material_method_hints")
|
| 243 |
else:
|
|
|
|
| 244 |
reason_codes.append("no_explicit_method_cue")
|
|
|
|
| 245 |
|
| 246 |
capability = method_capability(chosen)
|
| 247 |
return {
|
| 248 |
"resolver_version": METHOD_RESOLVER_VERSION,
|
| 249 |
"shadow_only": False,
|
| 250 |
-
"method_family": chosen
|
| 251 |
"confidence": confidence,
|
| 252 |
"reason_codes": reason_codes,
|
| 253 |
"title_keyword_hits": hits,
|
| 254 |
-
"material_hint_families":
|
| 255 |
"material_count": len(descriptors),
|
| 256 |
"derived_policy_lane": capability.get("legacy_policy_lane"),
|
| 257 |
"capability": capability,
|
|
@@ -279,35 +270,26 @@ def resolve_generation_preflight(
|
|
| 279 |
) -> dict[str, Any]:
|
| 280 |
"""Resolve method + capability before any task/quota creation.
|
| 281 |
|
| 282 |
-
A
|
| 283 |
-
|
|
|
|
|
|
|
| 284 |
"""
|
| 285 |
resolution = resolve_method_family(title, keywords, materials=materials)
|
| 286 |
family = str(resolution.get("method_family") or "").strip().casefold()
|
| 287 |
-
confidence = str(resolution.get("confidence") or "").strip().upper()
|
| 288 |
|
| 289 |
confirmed = str(confirmed_method_family or "").strip().casefold()
|
| 290 |
-
if
|
| 291 |
-
|
| 292 |
-
|
| 293 |
-
|
| 294 |
-
|
| 295 |
-
|
| 296 |
-
|
| 297 |
-
|
| 298 |
-
|
| 299 |
-
|
| 300 |
-
|
| 301 |
-
})
|
| 302 |
-
else:
|
| 303 |
-
return {
|
| 304 |
-
"can_start_generation": False,
|
| 305 |
-
"block_reason": "method_confirmation_required",
|
| 306 |
-
"resolution": resolution,
|
| 307 |
-
"method_family": family or "undetermined",
|
| 308 |
-
"legacy_policy_lane": None,
|
| 309 |
-
"capability": method_capability(family),
|
| 310 |
-
}
|
| 311 |
|
| 312 |
capability = method_capability(family)
|
| 313 |
lane = str(capability.get("legacy_policy_lane") or "").strip().casefold() or None
|
|
@@ -315,7 +297,7 @@ def resolve_generation_preflight(
|
|
| 315 |
if family not in METHOD_FAMILIES or not lane:
|
| 316 |
return {
|
| 317 |
"can_start_generation": False,
|
| 318 |
-
"block_reason": "
|
| 319 |
"resolution": resolution,
|
| 320 |
"method_family": family or "undetermined",
|
| 321 |
"legacy_policy_lane": None,
|
|
|
|
| 1 |
# -*- coding: utf-8 -*-
|
| 2 |
+
"""Deterministic research-design resolver and capability preflight for SmartPaper.
|
| 3 |
|
| 4 |
+
U1-R2B derives an academic ``method_family`` from Title + Keywords only, maps
|
| 5 |
+
that family to the legacy AMJ/ASQ policy lane, and blocks unsupported method
|
| 6 |
+
families before task/quota creation. When no design cue is detected, the
|
| 7 |
+
resolver defaults to qualitative research. A user's manual design adjustment
|
| 8 |
+
is authoritative for the current Title + Keywords signature, but it never
|
| 9 |
+
bypasses the capability gate. This module never selects providers/models and
|
| 10 |
+
never rewrites Title/Keywords.
|
| 11 |
"""
|
| 12 |
from __future__ import annotations
|
| 13 |
|
|
|
|
| 15 |
import re
|
| 16 |
from typing import Any, Iterable
|
| 17 |
|
| 18 |
+
METHOD_RESOLVER_VERSION = "smartpaper-auto-method-resolver-v3"
|
| 19 |
METHOD_CAPABILITY_REGISTRY_VERSION = "smartpaper-method-capability-registry-v2"
|
| 20 |
|
| 21 |
METHOD_FAMILIES = (
|
|
|
|
| 200 |
*,
|
| 201 |
materials: Iterable[Any] | None = None,
|
| 202 |
) -> dict[str, Any]:
|
| 203 |
+
"""Resolve one academic research-design family from Title + Keywords.
|
| 204 |
|
| 205 |
+
``materials`` remains in the public signature for backward compatibility,
|
| 206 |
+
but U1-R2B deliberately does not use uploaded material names or contents to
|
| 207 |
+
infer the design. If no explicit design cue is found, qualitative research
|
| 208 |
+
is selected as the non-blocking default.
|
| 209 |
"""
|
| 210 |
source_title = _normalized_text(title)
|
| 211 |
source_keywords = _keyword_items(keywords)
|
|
|
|
| 221 |
chosen = family
|
| 222 |
|
| 223 |
descriptors = _material_descriptors(materials)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 224 |
|
| 225 |
+
confidence = "AUTO_DETECTED" if chosen else "DEFAULT_QUALITATIVE"
|
|
|
|
|
|
|
|
|
|
| 226 |
reason_codes: list[str] = []
|
| 227 |
if chosen:
|
| 228 |
reason_codes.append("explicit_title_keyword_method_cue")
|
| 229 |
conflicting = [row["method_family"] for row in hits if row["method_family"] != chosen]
|
| 230 |
if conflicting:
|
| 231 |
reason_codes.append("lower_priority_method_cues_present")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 232 |
else:
|
| 233 |
+
chosen = "qualitative"
|
| 234 |
reason_codes.append("no_explicit_method_cue")
|
| 235 |
+
reason_codes.append("default_qualitative")
|
| 236 |
|
| 237 |
capability = method_capability(chosen)
|
| 238 |
return {
|
| 239 |
"resolver_version": METHOD_RESOLVER_VERSION,
|
| 240 |
"shadow_only": False,
|
| 241 |
+
"method_family": chosen,
|
| 242 |
"confidence": confidence,
|
| 243 |
"reason_codes": reason_codes,
|
| 244 |
"title_keyword_hits": hits,
|
| 245 |
+
"material_hint_families": [],
|
| 246 |
"material_count": len(descriptors),
|
| 247 |
"derived_policy_lane": capability.get("legacy_policy_lane"),
|
| 248 |
"capability": capability,
|
|
|
|
| 270 |
) -> dict[str, Any]:
|
| 271 |
"""Resolve method + capability before any task/quota creation.
|
| 272 |
|
| 273 |
+
A valid manual selection may override either an auto-detected design or the
|
| 274 |
+
qualitative fallback. Capability validation always runs after the manual
|
| 275 |
+
selection, so an unsupported advanced method still cannot create a task or
|
| 276 |
+
reserve quota.
|
| 277 |
"""
|
| 278 |
resolution = resolve_method_family(title, keywords, materials=materials)
|
| 279 |
family = str(resolution.get("method_family") or "").strip().casefold()
|
|
|
|
| 280 |
|
| 281 |
confirmed = str(confirmed_method_family or "").strip().casefold()
|
| 282 |
+
if confirmed in METHOD_FAMILIES and confirmed != family:
|
| 283 |
+
family = confirmed
|
| 284 |
+
capability = method_capability(family)
|
| 285 |
+
resolution = dict(resolution)
|
| 286 |
+
resolution.update({
|
| 287 |
+
"method_family": family,
|
| 288 |
+
"confidence": "USER_OVERRIDE",
|
| 289 |
+
"derived_policy_lane": capability.get("legacy_policy_lane"),
|
| 290 |
+
"capability": capability,
|
| 291 |
+
"reason_codes": list(resolution.get("reason_codes") or []) + ["user_override_method_family"],
|
| 292 |
+
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 293 |
|
| 294 |
capability = method_capability(family)
|
| 295 |
lane = str(capability.get("legacy_policy_lane") or "").strip().casefold() or None
|
|
|
|
| 297 |
if family not in METHOD_FAMILIES or not lane:
|
| 298 |
return {
|
| 299 |
"can_start_generation": False,
|
| 300 |
+
"block_reason": "method_resolution_invalid",
|
| 301 |
"resolution": resolution,
|
| 302 |
"method_family": family or "undetermined",
|
| 303 |
"legacy_policy_lane": None,
|
i18n.py
CHANGED
|
@@ -276,25 +276,26 @@ TEXTS: dict[str, dict[str, str]] = {
|
|
| 276 |
"download_asq_template": "📥 一键下载 TXT 访谈模板",
|
| 277 |
"start_asq": "🚀 启动 ASQ 模式生成",
|
| 278 |
"research_materials_label": "研究资料(可选)",
|
| 279 |
-
"research_materials_help": "支持 PDF、TXT、DOC、DOCX、CSV、XLS、XLSX。
|
| 280 |
"drop_research_materials": "将研究资料拖到这里",
|
| 281 |
"limit_research_materials": "每个文件最大 1 GB · PDF, TXT, DOC, DOCX, CSV, XLS, XLSX",
|
| 282 |
"material_document_use_label": "如何使用上传的 PDF/DOC/DOCX 文件?",
|
| 283 |
"material_use_reference": "作为参考文献资料",
|
| 284 |
"material_use_research": "作为研究资料",
|
| 285 |
-
"detected_method_label": "研究设计(自动识别)",
|
| 286 |
-
"method_detection_explanation": "
|
| 287 |
-
"method_confirm_label": "
|
| 288 |
-
"method_confirm_placeholder": "请选择研究
|
| 289 |
-
"method_confirmation_required": "
|
| 290 |
-
"
|
| 291 |
-
"
|
| 292 |
-
"
|
| 293 |
-
"
|
| 294 |
-
"
|
| 295 |
-
"
|
|
|
|
| 296 |
"method_meta_analysis": "元分析",
|
| 297 |
-
"method_panel_econometrics": "面板计量
|
| 298 |
"method_bibliometric_integrative_review": "文献计量与整合性综述",
|
| 299 |
"adaptive_template_expander": "💡 推荐模板(可选)",
|
| 300 |
"download_research_template": "📥 下载研究资料模板",
|
|
@@ -517,26 +518,27 @@ TEXTS: dict[str, dict[str, str]] = {
|
|
| 517 |
"download_asq_template": "📥 Download TXT Interview Template",
|
| 518 |
"start_asq": "🚀 Start ASQ Generation",
|
| 519 |
"research_materials_label": "Research Materials (Optional)",
|
| 520 |
-
"research_materials_help": "Supports PDF, TXT, DOC, DOCX, CSV, XLS, and XLSX.
|
| 521 |
"drop_research_materials": "Drag research materials here",
|
| 522 |
"limit_research_materials": "Up to 1 GB per file · PDF, TXT, DOC, DOCX, CSV, XLS, XLSX",
|
| 523 |
"material_document_use_label": "How should SmartPaper use the uploaded PDF/DOC/DOCX files?",
|
| 524 |
"material_use_reference": "Use as reference literature",
|
| 525 |
"material_use_research": "Use as research materials",
|
| 526 |
-
"detected_method_label": "Research Design (Auto-detected)",
|
| 527 |
-
"method_detection_explanation": "
|
| 528 |
-
"method_confirm_label": "
|
| 529 |
-
"method_confirm_placeholder": "Select a
|
| 530 |
-
"method_confirmation_required": "The
|
| 531 |
-
"
|
| 532 |
-
"
|
| 533 |
-
"
|
| 534 |
-
"
|
| 535 |
-
"
|
| 536 |
-
"
|
|
|
|
| 537 |
"method_meta_analysis": "Meta-Analysis",
|
| 538 |
-
"method_panel_econometrics": "Panel Econometric
|
| 539 |
-
"method_bibliometric_integrative_review": "Bibliometric and Integrative Review",
|
| 540 |
"adaptive_template_expander": "💡 Recommended Template (Optional)",
|
| 541 |
"download_research_template": "📥 Download Research Materials Template",
|
| 542 |
"template_help_survey_path": "A variable-level or statistical-results table is recommended. If no data are uploaded, SmartPaper may construct draft evidence under the project provenance rules.",
|
|
@@ -758,26 +760,27 @@ TEXTS: dict[str, dict[str, str]] = {
|
|
| 758 |
"download_asq_template": "📥 Скачать TXT-шаблон интервью",
|
| 759 |
"start_asq": "🚀 Запустить формирование в режиме ASQ",
|
| 760 |
"research_materials_label": "Материалы исследования (необязательно)",
|
| 761 |
-
"research_materials_help": "Поддерживаются PDF, TXT, DOC, DOCX, CSV, XLS и XLSX.
|
| 762 |
"drop_research_materials": "Перетащите исследовательские материалы сюда",
|
| 763 |
"limit_research_materials": "До 1 ГБ на файл · PDF, TXT, DOC, DOCX, CSV, XLS, XLSX",
|
| 764 |
"material_document_use_label": "Как использовать загруженные файлы PDF/DOC/DOCX?",
|
| 765 |
"material_use_reference": "Как научные источники",
|
| 766 |
"material_use_research": "Как исследовательские материалы",
|
| 767 |
-
"detected_method_label": "Дизайн исследования (определяется автоматически)",
|
| 768 |
-
"method_detection_explanation": "
|
| 769 |
-
"method_confirm_label": "
|
| 770 |
-
"method_confirm_placeholder": "Выберите
|
| 771 |
-
"method_confirmation_required": "
|
| 772 |
-
"
|
| 773 |
-
"
|
| 774 |
-
"
|
| 775 |
-
"
|
|
|
|
| 776 |
"method_qualitative": "Качественное исследование",
|
| 777 |
-
"method_fsqca": "К
|
| 778 |
-
"method_meta_analysis": "Мета
|
| 779 |
-
"method_panel_econometrics": "
|
| 780 |
-
"method_bibliometric_integrative_review": "Библиометрический и интегративный обзор",
|
| 781 |
"adaptive_template_expander": "💡 Рекомендуемый шаблон (необязательно)",
|
| 782 |
"download_research_template": "📥 Скачать шаблон исследовательских материалов",
|
| 783 |
"template_help_survey_path": "Рекомендуется таблица переменных или статистических результатов. При отсутствии данных SmartPaper может сформировать черновые доказательные материалы в рамках правил происхождения данных.",
|
|
@@ -999,26 +1002,27 @@ TEXTS: dict[str, dict[str, str]] = {
|
|
| 999 |
"download_asq_template": "📥 TXT сұхбат үлгісін жүктеу",
|
| 1000 |
"start_asq": "🚀 ASQ режимінде дайындауды бастау",
|
| 1001 |
"research_materials_label": "Зерттеу материалдары (міндетті емес)",
|
| 1002 |
-
"research_materials_help": "PDF, TXT, DOC, DOCX, CSV, XLS және XLSX форматтары қолдау табады.
|
| 1003 |
"drop_research_materials": "Зерттеу материалдарын ос�� жерге сүйреп әкеліңіз",
|
| 1004 |
"limit_research_materials": "Әр файлға 1 ГБ дейін · PDF, TXT, DOC, DOCX, CSV, XLS, XLSX",
|
| 1005 |
"material_document_use_label": "Жүктелген PDF/DOC/DOCX файлдарын қалай пайдалану керек?",
|
| 1006 |
"material_use_reference": "Ғылыми дереккөз ретінде",
|
| 1007 |
"material_use_research": "Зерттеу материалы ретінде",
|
| 1008 |
-
"detected_method_label": "Зерттеу дизайны (автоматты түрде анықталады)",
|
| 1009 |
-
"method_detection_explanation": "
|
| 1010 |
-
"method_confirm_label": "Зерттеу дизайнын р
|
| 1011 |
-
"method_confirm_placeholder": "Зерттеу
|
| 1012 |
-
"method_confirmation_required": "
|
| 1013 |
-
"
|
| 1014 |
-
"
|
| 1015 |
-
"
|
| 1016 |
-
"
|
|
|
|
| 1017 |
"method_qualitative": "Сапалық зерттеу",
|
| 1018 |
-
"method_fsqca": "
|
| 1019 |
"method_meta_analysis": "Мета-талдау",
|
| 1020 |
-
"method_panel_econometrics": "Панельдік эконометри
|
| 1021 |
-
"method_bibliometric_integrative_review": "Библиометриялық және интегративті шолу",
|
| 1022 |
"adaptive_template_expander": "💡 Ұсынылатын үлгі (міндетті емес)",
|
| 1023 |
"download_research_template": "📥 Зерттеу материалдары үлгісін жүктеу",
|
| 1024 |
"template_help_survey_path": "Айнымалылар немесе статистикалық нәтижелер кестесі ұсынылады. Дерек жүктелмесе, SmartPaper жоба ережелеріне сәйкес бастапқы нұсқаға арналған көмекші дәлелдерді құра алады.",
|
|
|
|
| 276 |
"download_asq_template": "📥 一键下载 TXT 访谈模板",
|
| 277 |
"start_asq": "🚀 启动 ASQ 模式生成",
|
| 278 |
"research_materials_label": "研究资料(可选)",
|
| 279 |
+
"research_materials_help": "支持 PDF、TXT、DOC、DOCX、CSV、XLS、XLSX。上传资料用于辅助论文生成;研究设计仅根据论文题目和关键词自动识别。",
|
| 280 |
"drop_research_materials": "将研究资料拖到这里",
|
| 281 |
"limit_research_materials": "每个文件最大 1 GB · PDF, TXT, DOC, DOCX, CSV, XLS, XLSX",
|
| 282 |
"material_document_use_label": "如何使用上传的 PDF/DOC/DOCX 文件?",
|
| 283 |
"material_use_reference": "作为参考文献资料",
|
| 284 |
"material_use_research": "作为研究资料",
|
| 285 |
+
"detected_method_label": "研究设计(自动识别,可调整)",
|
| 286 |
+
"method_detection_explanation": "基于论文题目和关键词自动识别研究设计。未识别时默认质性研究,可手动调整。",
|
| 287 |
+
"method_confirm_label": "调整研究设计",
|
| 288 |
+
"method_confirm_placeholder": "请选择研究设计",
|
| 289 |
+
"method_confirmation_required": "研究设计状态异常,请重新选择研究设计。",
|
| 290 |
+
"method_resolution_invalid": "研究设计状态异常,请重新选择研究设计。",
|
| 291 |
+
"method_not_supported": "当前研究设计为“{method}”。该研究设计的专用生成引擎尚未开放;本次不会创建任务,也不会占用额度。",
|
| 292 |
+
"method_supported": "当前研究设计为“{method}”。系统将按对应研究流程生成论文。",
|
| 293 |
+
"method_undetermined": "质性研究(默认)",
|
| 294 |
+
"method_survey_path": "问卷量化研究",
|
| 295 |
+
"method_qualitative": "质性研究",
|
| 296 |
+
"method_fsqca": "模糊集定性比较分析(fsQCA)",
|
| 297 |
"method_meta_analysis": "元分析",
|
| 298 |
+
"method_panel_econometrics": "面板数据计量分析",
|
| 299 |
"method_bibliometric_integrative_review": "文献计量与整合性综述",
|
| 300 |
"adaptive_template_expander": "💡 推荐模板(可选)",
|
| 301 |
"download_research_template": "📥 下载研究资料模板",
|
|
|
|
| 518 |
"download_asq_template": "📥 Download TXT Interview Template",
|
| 519 |
"start_asq": "🚀 Start ASQ Generation",
|
| 520 |
"research_materials_label": "Research Materials (Optional)",
|
| 521 |
+
"research_materials_help": "Supports PDF, TXT, DOC, DOCX, CSV, XLS, and XLSX. Uploaded files support paper generation; Research Design is identified from the Title and Keywords only.",
|
| 522 |
"drop_research_materials": "Drag research materials here",
|
| 523 |
"limit_research_materials": "Up to 1 GB per file · PDF, TXT, DOC, DOCX, CSV, XLS, XLSX",
|
| 524 |
"material_document_use_label": "How should SmartPaper use the uploaded PDF/DOC/DOCX files?",
|
| 525 |
"material_use_reference": "Use as reference literature",
|
| 526 |
"material_use_research": "Use as research materials",
|
| 527 |
+
"detected_method_label": "Research Design (Auto-detected, Adjustable)",
|
| 528 |
+
"method_detection_explanation": "Automatically identifies the Research Design from the Title and Keywords. If none is identified, Qualitative Research is used by default. You can adjust it manually.",
|
| 529 |
+
"method_confirm_label": "Adjust Research Design",
|
| 530 |
+
"method_confirm_placeholder": "Select a Research Design",
|
| 531 |
+
"method_confirmation_required": "The Research Design state is invalid. Please select a Research Design again.",
|
| 532 |
+
"method_resolution_invalid": "The Research Design state is invalid. Please select a Research Design again.",
|
| 533 |
+
"method_not_supported": "Current Research Design: {method}. Its dedicated generation engine is not yet enabled, so no task will be created and no quota will be used.",
|
| 534 |
+
"method_supported": "Current Research Design: {method}. SmartPaper will use the corresponding research workflow.",
|
| 535 |
+
"method_undetermined": "Qualitative Research (Default)",
|
| 536 |
+
"method_survey_path": "Survey-Based Quantitative Research",
|
| 537 |
+
"method_qualitative": "Qualitative Research",
|
| 538 |
+
"method_fsqca": "Fuzzy-Set Qualitative Comparative Analysis (fsQCA)",
|
| 539 |
"method_meta_analysis": "Meta-Analysis",
|
| 540 |
+
"method_panel_econometrics": "Panel Data Econometric Analysis",
|
| 541 |
+
"method_bibliometric_integrative_review": "Bibliometric Analysis and Integrative Literature Review",
|
| 542 |
"adaptive_template_expander": "💡 Recommended Template (Optional)",
|
| 543 |
"download_research_template": "📥 Download Research Materials Template",
|
| 544 |
"template_help_survey_path": "A variable-level or statistical-results table is recommended. If no data are uploaded, SmartPaper may construct draft evidence under the project provenance rules.",
|
|
|
|
| 760 |
"download_asq_template": "📥 Скачать TXT-шаблон интервью",
|
| 761 |
"start_asq": "🚀 Запустить формирование в режиме ASQ",
|
| 762 |
"research_materials_label": "Материалы исследования (необязательно)",
|
| 763 |
+
"research_materials_help": "Поддерживаются PDF, TXT, DOC, DOCX, CSV, XLS и XLSX. Загруженные файлы используются как дополнительные исследовательские или справочные материалы; дизайн исследования определяется по названию статьи и ключевым словам.",
|
| 764 |
"drop_research_materials": "Перетащите исследовательские материалы сюда",
|
| 765 |
"limit_research_materials": "До 1 ГБ на файл · PDF, TXT, DOC, DOCX, CSV, XLS, XLSX",
|
| 766 |
"material_document_use_label": "Как использовать загруженные файлы PDF/DOC/DOCX?",
|
| 767 |
"material_use_reference": "Как научные источники",
|
| 768 |
"material_use_research": "Как исследовательские материалы",
|
| 769 |
+
"detected_method_label": "Дизайн исследования (определяется автоматически, можно изменить)",
|
| 770 |
+
"method_detection_explanation": "Дизайн исследования определяется автоматически по названию статьи и ключевым словам. Если определить его не удаётся, по умолчанию выбирается качественное исследование. Выбор можно изменить вручную.",
|
| 771 |
+
"method_confirm_label": "Изменить дизайн исследования",
|
| 772 |
+
"method_confirm_placeholder": "Выберите дизайн исследования",
|
| 773 |
+
"method_confirmation_required": "Некорректное состояние дизайна исследования. Выберите дизайн исследования повторно.",
|
| 774 |
+
"method_resolution_invalid": "Некорректное состояние дизайна исследования. Выберите дизайн исследования повторно.",
|
| 775 |
+
"method_not_supported": "Текущий дизайн исследования: «{method}». Специализированный движок для этого дизайна пока не включён, поэтому задача не будет создана и квота не будет списана.",
|
| 776 |
+
"method_supported": "Текущий дизайн исследования: «{method}». SmartPaper применит соответствующий исследовательский процесс.",
|
| 777 |
+
"method_undetermined": "Качественное исследование (по умолчанию)",
|
| 778 |
+
"method_survey_path": "Количественное исследование на основе опроса",
|
| 779 |
"method_qualitative": "Качественное исследование",
|
| 780 |
+
"method_fsqca": "Качественный сравнительный анализ на основе нечётких множеств (fsQCA)",
|
| 781 |
+
"method_meta_analysis": "Метаанализ",
|
| 782 |
+
"method_panel_econometrics": "Эконометрический анализ панельных данных",
|
| 783 |
+
"method_bibliometric_integrative_review": "Библиометрический анализ и интегративный обзор литературы",
|
| 784 |
"adaptive_template_expander": "💡 Рекомендуемый шаблон (необязательно)",
|
| 785 |
"download_research_template": "📥 Скачать шаблон исследовательских материалов",
|
| 786 |
"template_help_survey_path": "Рекомендуется таблица переменных или статистических результатов. При отсутствии данных SmartPaper может сформировать черновые доказательные материалы в рамках правил происхождения данных.",
|
|
|
|
| 1002 |
"download_asq_template": "📥 TXT сұхбат үлгісін жүктеу",
|
| 1003 |
"start_asq": "🚀 ASQ режимінде дайындауды бастау",
|
| 1004 |
"research_materials_label": "Зерттеу материалдары (міндетті емес)",
|
| 1005 |
+
"research_materials_help": "PDF, TXT, DOC, DOCX, CSV, XLS және XLSX форматтары қолдау табады. Жүктелген файлдар қосымша зерттеу немесе анықтамалық материал ретінде пайдаланылады; зерттеу дизайны мақала тақырыбы мен кілт сөздер бойынша анықталады.",
|
| 1006 |
"drop_research_materials": "Зерттеу материалдарын ос�� жерге сүйреп әкеліңіз",
|
| 1007 |
"limit_research_materials": "Әр файлға 1 ГБ дейін · PDF, TXT, DOC, DOCX, CSV, XLS, XLSX",
|
| 1008 |
"material_document_use_label": "Жүктелген PDF/DOC/DOCX файлдарын қалай пайдалану керек?",
|
| 1009 |
"material_use_reference": "Ғылыми дереккөз ретінде",
|
| 1010 |
"material_use_research": "Зерттеу материалы ретінде",
|
| 1011 |
+
"detected_method_label": "Зерттеу дизайны (автоматты түрде анықталады, өзгертуге болады)",
|
| 1012 |
+
"method_detection_explanation": "Зерттеу дизайны мақала тақырыбы мен кілт сөздер негізінде автоматты түрде анықталады. Анықталмаса, әдепкі бойынша сапалық зерттеу таңдалады. Таңдауды қолмен өзгертуге болады.",
|
| 1013 |
+
"method_confirm_label": "Зерттеу дизайнын өзгерту",
|
| 1014 |
+
"method_confirm_placeholder": "Зерттеу дизайнын таңдаңыз",
|
| 1015 |
+
"method_confirmation_required": "Зерттеу дизайнының күйі жарамсыз. Зерттеу дизайнын қайта таңдаңыз.",
|
| 1016 |
+
"method_resolution_invalid": "Зерттеу дизайнының күйі жарамсыз. Зерттеу дизайнын қайта таңдаңыз.",
|
| 1017 |
+
"method_not_supported": "Ағымдағы зерттеу дизайны: «{method}». Бұл дизайнның арнайы генерация қозғалтқышы әлі қосылмаған, сондықтан тапсырма құрылмайды және квота пайдаланылмайды.",
|
| 1018 |
+
"method_supported": "Ағымдағы зерттеу дизайны: «{method}». SmartPaper тиісті зерттеу үдерісін қолданады.",
|
| 1019 |
+
"method_undetermined": "Сапалық зерттеу (әдепкі)",
|
| 1020 |
+
"method_survey_path": "Сауалнамаға негізделген сандық зерттеу",
|
| 1021 |
"method_qualitative": "Сапалық зерттеу",
|
| 1022 |
+
"method_fsqca": "Бұлыңғыр жиындарға негізделген сапалық салыстырмалы талдау (fsQCA)",
|
| 1023 |
"method_meta_analysis": "Мета-талдау",
|
| 1024 |
+
"method_panel_econometrics": "Панельдік деректерді эконометриялық талдау",
|
| 1025 |
+
"method_bibliometric_integrative_review": "Библиометриялық талдау және әдебиеттерге интегративті шолу",
|
| 1026 |
"adaptive_template_expander": "💡 Ұсынылатын үлгі (міндетті емес)",
|
| 1027 |
"download_research_template": "📥 Зерттеу материалдары үлгісін жүктеу",
|
| 1028 |
"template_help_survey_path": "Айнымалылар немесе статистикалық нәтижелер кестесі ұсынылады. Дерек жүктелмесе, SmartPaper жоба ережелеріне сәйкес бастапқы нұсқаға арналған көмекші дәлелдерді құра алады.",
|