Skip to content

Commit 2683a2f

Browse files
committed
Merge branch 'main' into bc/voice_agent
2 parents 5bdff0a + 40a1089 commit 2683a2f

46 files changed

Lines changed: 3434 additions & 666 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gemini/styleguide.md

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
# AgentScope Code Review Guide
2+
3+
You should conduct a strict code review. Each requirement is labeled with priority:
4+
- **[MUST]** must be satisfied or PR will be rejected
5+
- **[SHOULD]** strongly recommended
6+
- **[MAY]** optional suggestion
7+
8+
## 1. Code Quality
9+
10+
### [MUST] Lazy Loading
11+
- Third-party library dependencies should be imported at the point of use, avoid centralized imports at file top
12+
- The `Third-party library` refers to libraries not included in the `dependencies` variable in `pyproject.toml`.
13+
- For base class imports, use factory pattern:
14+
```python
15+
def get_xxx_cls() -> "MyClass":
16+
from xxx import BaseClass
17+
class MyClass(BaseClass): ...
18+
return MyClass
19+
```
20+
21+
### [SHOULD] Code Conciseness
22+
After understanding the code intent, check if it can be optimized:
23+
- Avoid unnecessary temporary variables
24+
- Merge duplicate code blocks
25+
- Prioritize reusing existing utility functions
26+
27+
### [MUST] Encapsulation Standards
28+
- All Python files under `src/agentscope` should be named with `_` prefix, and exposure controlled through `__init__.py`
29+
- Classes and functions used internally by the framework that don't need to be exposed to users must be named with `_` prefix
30+
31+
## 2. [MUST] Code Security
32+
- Prohibit hardcoding API keys/tokens/passwords
33+
- Use environment variables or configuration files for management
34+
- Check for debug information and temporary credentials
35+
- Check for injection attack risks (SQL/command/code injection, etc.)
36+
37+
## 3. [MUST] Testing & Dependencies
38+
- New features must include unit tests
39+
- New dependencies need to be added to the corresponding section in `pyproject.toml`
40+
- Dependencies for non-core scenarios should not be added to the minimal dependency list
41+
42+
## 4. Code Standards
43+
44+
### [MUST] Comment Standards
45+
- **Use English**
46+
- All classes/methods must have complete docstrings, strictly following the template:
47+
```python
48+
def func(a: str, b: int | None = None) -> str:
49+
"""{description}
50+
51+
Args:
52+
a (`str`):
53+
The argument a
54+
b (`int | None`, optional):
55+
The argument b
56+
57+
Returns:
58+
`str`:
59+
The return str
60+
"""
61+
```
62+
- Use reStructuredText syntax for special content:
63+
```python
64+
class MyClass:
65+
"""xxx
66+
67+
`Example link <https://xxx>`_
68+
69+
.. note:: Example note
70+
71+
.. tip:: Example tip
72+
73+
.. important:: Example important info
74+
75+
.. code-block:: python
76+
77+
def hello_world():
78+
print("Hello world!")
79+
80+
"""
81+
```
82+
83+
### [MUST] Pre-commit Checks
84+
- **Strict review**: In most cases, code should be modified rather than skipping checks
85+
- **File-level check skipping is prohibited**
86+
- Only allowed skip: agent class system prompt parameters (to avoid `\n` formatting issues)
87+
88+
---
89+
90+
## 5. Git Standards
91+
92+
### [MUST] PR Title
93+
- Follow Conventional Commits
94+
- Must use prefixes: `feat/fix/docs/ci/refactor/test`, etc.
95+
- Format: `feat(scope): description`
96+
- Example: `feat(memory): add redis cache support`

.github/copilot-instructions.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# AgentScope Instructions
1+
# AgentScope Code Review Guide
22

33
You should conduct a strict code review. Each requirement is labeled with priority:
44
- **[MUST]** must be satisfied or PR will be rejected
@@ -9,7 +9,8 @@ You should conduct a strict code review. Each requirement is labeled with priori
99

1010
### [MUST] Lazy Loading
1111
- Third-party library dependencies should be imported at the point of use, avoid centralized imports at file top
12-
- Use factory pattern to import base classes:
12+
- The `Third-party library` refers to libraries not included in the `dependencies` variable in `pyproject.toml`.
13+
- For base class imports, use factory pattern:
1314
```python
1415
def get_xxx_cls() -> "MyClass":
1516
from xxx import BaseClass
@@ -35,7 +36,7 @@ After understanding the code intent, check if it can be optimized:
3536

3637
## 3. [MUST] Testing & Dependencies
3738
- New features must include unit tests
38-
- New dependencies need to be added to `pyproject.toml`
39+
- New dependencies need to be added to the corresponding section in `pyproject.toml`
3940
- Dependencies for non-core scenarios should not be added to the minimal dependency list
4041

4142
## 4. Code Standards

.github/scripts/update_news.py

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
#!/usr/bin/env python3
2+
# -*- coding: utf-8 -*-
3+
"""
4+
Script to automatically update NEWS section in README files.
5+
Reads the first 10 news items from docs/NEWS.md and updates README.md and
6+
README_zh.md.
7+
"""
8+
9+
from pathlib import Path
10+
11+
12+
def read_news_items(news_file: Path, max_items: int = 10) -> list[str]:
13+
"""
14+
Read news items from NEWS.md file.
15+
16+
Args:
17+
news_file (`Path`):
18+
Path to the NEWS.md file
19+
max_items (`int`, optional):
20+
Maximum number of items to read
21+
22+
Returns:
23+
`list[str]`:
24+
List of news items
25+
"""
26+
with open(news_file, "r", encoding="utf-8") as f:
27+
content = f.read()
28+
29+
# Split by lines that start with "- **["
30+
lines = content.strip().split("\n")
31+
news_items = []
32+
33+
for line in lines:
34+
if line.strip().startswith("- **["):
35+
news_items.append(line)
36+
if len(news_items) >= max_items:
37+
break
38+
39+
return news_items
40+
41+
42+
def update_readme(
43+
readme_file: Path,
44+
news_items: list[str],
45+
) -> None:
46+
"""
47+
Update the NEWS section in README file using HTML comment markers.
48+
49+
Args:
50+
readme_file (`Path`):
51+
Path to the README file
52+
news_items (`list[str]`):
53+
List of news items to insert
54+
"""
55+
with open(readme_file, "r", encoding="utf-8") as f:
56+
content = f.read()
57+
58+
# Use HTML comment markers to identify the NEWS section
59+
begin_marker = "<!-- BEGIN NEWS -->"
60+
end_marker = "<!-- END NEWS -->"
61+
62+
if begin_marker not in content or end_marker not in content:
63+
print(f"⚠️ NEWS markers not found in {readme_file.name}")
64+
print(
65+
f" Please add '{begin_marker}' and '{end_marker}' to mark the "
66+
f"NEWS section",
67+
)
68+
return
69+
70+
# Find positions of markers
71+
begin_pos = content.find(begin_marker)
72+
end_pos = content.find(end_marker)
73+
74+
if begin_pos == -1 or end_pos == -1 or begin_pos >= end_pos:
75+
print(f"❌ Invalid NEWS markers in {readme_file.name}")
76+
return
77+
78+
# Create new NEWS content
79+
news_content = "\n".join(news_items)
80+
81+
# Replace content between markers
82+
new_content = (
83+
content[: begin_pos + len(begin_marker)]
84+
+ "\n"
85+
+ news_content
86+
+ "\n"
87+
+ content[end_pos:]
88+
)
89+
90+
with open(readme_file, "w", encoding="utf-8") as f:
91+
f.write(new_content)
92+
93+
print(f"✅ Updated {readme_file.name}")
94+
95+
96+
def main() -> None:
97+
"""Main function to update NEWS in README files."""
98+
# Define paths
99+
repo_root = Path(__file__).parent.parent.parent
100+
news_file_en = repo_root / "docs" / "NEWS.md"
101+
news_file_zh = repo_root / "docs" / "NEWS_zh.md"
102+
readme_en = repo_root / "README.md"
103+
readme_zh = repo_root / "README_zh.md"
104+
105+
# Update English README from NEWS.md
106+
if news_file_en.exists():
107+
print(f"📖 Reading news items from {news_file_en}")
108+
news_items_en = read_news_items(news_file_en, max_items=10)
109+
print(f"📰 Found {len(news_items_en)} English news items")
110+
111+
if news_items_en and readme_en.exists():
112+
print(f"📝 Updating {readme_en.name}...")
113+
update_readme(readme_en, news_items_en)
114+
elif not news_items_en:
115+
print("⚠️ No English news items found")
116+
else:
117+
print(f"⚠️ {readme_en} not found")
118+
else:
119+
print(f"❌ NEWS.md not found at {news_file_en}")
120+
121+
# Update Chinese README from NEWS_zh.md
122+
if news_file_zh.exists() and news_file_zh.stat().st_size > 0:
123+
print(f"📖 Reading news items from {news_file_zh}")
124+
news_items_zh = read_news_items(news_file_zh, max_items=10)
125+
print(f"📰 Found {len(news_items_zh)} Chinese news items")
126+
127+
if news_items_zh and readme_zh.exists():
128+
print(f"📝 Updating {readme_zh.name}...")
129+
update_readme(readme_zh, news_items_zh)
130+
elif not news_items_zh:
131+
print("⚠️ No Chinese news items found")
132+
else:
133+
print(f"⚠️ {readme_zh} not found")
134+
else:
135+
print(
136+
f"⚠️ NEWS_zh.md not found or empty at {news_file_zh}, "
137+
f"using English news for Chinese README",
138+
)
139+
# Fallback: use English news for Chinese README if NEWS_zh.md
140+
# doesn't exist
141+
if news_file_en.exists() and readme_zh.exists():
142+
print(f"📖 Reading news items from {news_file_en} (fallback)")
143+
news_items = read_news_items(news_file_en, max_items=10)
144+
if news_items:
145+
print(f"📝 Updating {readme_zh.name} with English news...")
146+
update_readme(readme_zh, news_items)
147+
148+
print("✨ All done!")
149+
150+
151+
if __name__ == "__main__":
152+
main()

.github/workflows/toc.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ on:
77
branches-ignore:
88
- 'main'
99

10+
# Prevent concurrent runs that modify README files
11+
concurrency:
12+
group: readme-updates-${{ github.ref }}
13+
cancel-in-progress: false
14+
1015
jobs:
1116
generateTOC:
1217
name: TOC Generator

.github/workflows/update_news.yml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
name: Update NEWS in README
2+
on:
3+
push:
4+
paths:
5+
- 'docs/NEWS.md'
6+
- 'docs/NEWS_zh.md'
7+
branches-ignore:
8+
- 'main'
9+
10+
# Prevent concurrent runs that modify README files
11+
concurrency:
12+
group: readme-updates-${{ github.ref }}
13+
cancel-in-progress: false
14+
15+
jobs:
16+
updateNews:
17+
name: NEWS Updater
18+
runs-on: ubuntu-latest
19+
steps:
20+
- uses: actions/checkout@v6
21+
with:
22+
fetch-depth: 0
23+
24+
- name: Set up Python
25+
uses: actions/setup-python@v6
26+
with:
27+
python-version: '3.10'
28+
29+
- name: Update NEWS in README files
30+
run: python .github/scripts/update_news.py
31+
32+
- name: Commit changes
33+
run: |
34+
git config --local user.email "github-actions[bot]@users.noreply.github.com"
35+
git config --local user.name "github-actions[bot]"
36+
git add README.md README_zh.md
37+
git diff --staged --quiet || git commit -m "docs: auto-sync NEWS section to README files"
38+
git push
39+

0 commit comments

Comments
 (0)