samlax12 commited on
Commit
73801d9
·
verified ·
1 Parent(s): c065653

Upload 142 files

Browse files
.dockerignore ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ __pycache__
2
+ *.pyc
3
+ *.pyo
4
+ .env.local
5
+ node_modules
6
+ frontend/node_modules
7
+ frontend/.git
8
+ _archive
9
+ .git
10
+ .gitattributes
11
+ *.md
12
+ !requirements.txt
13
+ auth.db
14
+ static/3d_plot_*.html
.env ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 基础API配置
2
+ API_KEY=sk-jkghlcicuaefjbytddyxcyvbnfeeamcgbxpnyegclgehvdxn
3
+ BASE_URL=https://api.siliconflow.cn/v1
4
+ EMBEDDING_MODEL=BAAI/bge-m3
5
+ RERANK_MODEL=BAAI/bge-reranker-v2-m3
6
+ VISION_MODEL=Qwen/Qwen2.5-VL-72B-Instruct
7
+
8
+ # Elasticsearch配置
9
+ ELASTICSEARCH_URL=https://samlax12-elastic.hf.space
10
+ PASSWORD=zhx123456
11
+
12
+ # 流式文本问答配置
13
+ STREAM_API_KEY=sk-ffa3deab3c064e8083cef468611656d1
14
+ STREAM_BASE_URL=https://api.deepseek.com/v1
15
+ STREAM_MODEL=deepseek-chat
16
+ DEFAULT_MODEL=deepseek-chat
17
+
18
+ # Flask和认证配置
19
+ SECRET_KEY=your_super_secret_key_2024_teachagent
20
+ JWT_SECRET=your_jwt_secret_key_2024_teachagent
21
+ JWT_ALGORITHM=HS256
22
+
23
+ # SMTP邮件配置
24
+ SMTP_HOST=
25
+ SMTP_PORT=
26
+ SMTP_USER=
27
+ SMTP_PASS=
28
+ FROM_EMAIL=
Dockerfile CHANGED
@@ -14,8 +14,10 @@ RUN pip install --no-cache-dir -r requirements.txt
14
  # 复制应用代码
15
  COPY . .
16
 
17
- # 确保目录存在
18
- RUN mkdir -p static uploads agents
 
 
19
 
20
  EXPOSE 7860
21
 
 
14
  # 复制应用代码
15
  COPY . .
16
 
17
+ # 确保目录存在(/data 为 HF Spaces 持久存储)
18
+ RUN mkdir -p static /data/agents /data/uploads
19
+
20
+ ENV DATA_DIR=/data
21
 
22
  EXPOSE 7860
23
 
agents/1.txt ADDED
File without changes
app.py CHANGED
@@ -28,6 +28,11 @@ load_dotenv()
28
  app = Flask(__name__)
29
  CORS(app)
30
 
 
 
 
 
 
31
  # 设置session密钥
32
  app.secret_key = os.getenv("SECRET_KEY", "your_secret_key_here")
33
 
@@ -40,8 +45,8 @@ app.register_blueprint(auth_bp, url_prefix='/api/auth')
40
 
41
  # 确保目录存在
42
  os.makedirs('static', exist_ok=True)
43
- os.makedirs('uploads', exist_ok=True)
44
- os.makedirs('agents', exist_ok=True)
45
 
46
  # 用于代码执行的上下文
47
  execution_contexts = {}
@@ -347,7 +352,7 @@ def student_view(agent_id):
347
  token = request.args.get('token', '')
348
 
349
  # 验证Agent存在
350
- agent_path = os.path.join('agents', f"{agent_id}.json")
351
  if not os.path.exists(agent_path):
352
  return render_template('error.html',
353
  message="找不到指定的Agent",
@@ -415,7 +420,7 @@ def student_chat(agent_id):
415
  return jsonify({"success": False, "message": "消息不能为空"}), 400
416
 
417
  # 验证Agent和令牌
418
- agent_path = os.path.join('agents', f"{agent_id}.json")
419
  if not os.path.exists(agent_path):
420
  return jsonify({"success": False, "message": "Agent不存在"}), 404
421
 
@@ -834,7 +839,7 @@ def verify_token():
834
 
835
  # 如果提供了agent_id,验证特定Agent的令牌
836
  if agent_id:
837
- agent_path = os.path.join('agents', f"{agent_id}.json")
838
  if not os.path.exists(agent_path):
839
  return jsonify({
840
  "success": False,
@@ -874,9 +879,9 @@ def verify_token():
874
  # 如果没有提供agent_id,搜索所有Agent
875
  valid_agent = None
876
 
877
- for filename in os.listdir('agents'):
878
  if filename.endswith('.json'):
879
- agent_path = os.path.join('agents', filename)
880
  with open(agent_path, 'r', encoding='utf-8') as f:
881
  agent_config = json.load(f)
882
 
@@ -929,9 +934,9 @@ def get_student_agents():
929
  # 这里简化为获取所有Agent
930
  agents = []
931
 
932
- for filename in os.listdir('agents'):
933
  if filename.endswith('.json'):
934
- agent_path = os.path.join('agents', filename)
935
  with open(agent_path, 'r', encoding='utf-8') as f:
936
  agent_config = json.load(f)
937
 
 
28
  app = Flask(__name__)
29
  CORS(app)
30
 
31
+ # 数据持久化目录(HuggingFace Spaces 用 /data,本地开发用当前目录)
32
+ DATA_DIR = os.getenv("DATA_DIR", ".")
33
+ AGENTS_DIR = os.path.join(DATA_DIR, "agents")
34
+ UPLOADS_DIR = os.path.join(DATA_DIR, "uploads")
35
+
36
  # 设置session密钥
37
  app.secret_key = os.getenv("SECRET_KEY", "your_secret_key_here")
38
 
 
45
 
46
  # 确保目录存在
47
  os.makedirs('static', exist_ok=True)
48
+ os.makedirs(UPLOADS_DIR, exist_ok=True)
49
+ os.makedirs(AGENTS_DIR, exist_ok=True)
50
 
51
  # 用于代码执行的上下文
52
  execution_contexts = {}
 
352
  token = request.args.get('token', '')
353
 
354
  # 验证Agent存在
355
+ agent_path = os.path.join(AGENTS_DIR,f"{agent_id}.json")
356
  if not os.path.exists(agent_path):
357
  return render_template('error.html',
358
  message="找不到指定的Agent",
 
420
  return jsonify({"success": False, "message": "消息不能为空"}), 400
421
 
422
  # 验证Agent和令牌
423
+ agent_path = os.path.join(AGENTS_DIR,f"{agent_id}.json")
424
  if not os.path.exists(agent_path):
425
  return jsonify({"success": False, "message": "Agent不存在"}), 404
426
 
 
839
 
840
  # 如果提供了agent_id,验证特定Agent的令牌
841
  if agent_id:
842
+ agent_path = os.path.join(AGENTS_DIR,f"{agent_id}.json")
843
  if not os.path.exists(agent_path):
844
  return jsonify({
845
  "success": False,
 
879
  # 如果没有提供agent_id,搜索所有Agent
880
  valid_agent = None
881
 
882
+ for filename in os.listdir(AGENTS_DIR):
883
  if filename.endswith('.json'):
884
+ agent_path = os.path.join(AGENTS_DIR,filename)
885
  with open(agent_path, 'r', encoding='utf-8') as f:
886
  agent_config = json.load(f)
887
 
 
934
  # 这里简化为获取所有Agent
935
  agents = []
936
 
937
+ for filename in os.listdir(AGENTS_DIR):
938
  if filename.endswith('.json'):
939
+ agent_path = os.path.join(AGENTS_DIR,filename)
940
  with open(agent_path, 'r', encoding='utf-8') as f:
941
  agent_config = json.load(f)
942
 
frontend/src/components/plugins/Visualization3D.jsx CHANGED
@@ -29,7 +29,7 @@ const Visualization3D = ({ code = '' }) => {
29
  const response = await api.post('/visualization/3d-surface', { code: targetCode });
30
  if (response.success) {
31
  // html_url 是相对于后端的路径,需要加上后端地址
32
- setHtmlUrl(`http://localhost:7860${response.html_url}`);
33
  } else {
34
  setError(response.message || '生成失败');
35
  }
 
29
  const response = await api.post('/visualization/3d-surface', { code: targetCode });
30
  if (response.success) {
31
  // html_url 是相对于后端的路径,需要加上后端地址
32
+ setHtmlUrl(response.html_url);
33
  } else {
34
  setError(response.message || '生成失败');
35
  }
frontend/src/pages/student/AgentChat.jsx CHANGED
@@ -152,7 +152,8 @@ const AgentChat = () => {
152
  try {
153
  // 发送请求到后端(SSE流式响应)
154
  // SSE 直连后端,绕过 Vite 代理避免缓冲
155
- const SSE_BASE = window.location.hostname === 'localhost' ? 'http://localhost:7860' : '';
 
156
  const response = await fetch(`${SSE_BASE}/api/student/chat/${agentId}`, {
157
  method: 'POST',
158
  headers: {
 
152
  try {
153
  // 发送请求到后端(SSE流式响应)
154
  // SSE 直连后端,绕过 Vite 代理避免缓冲
155
+ // 开发环境直连后端绕过 Vite 代理(避免 SSE 缓冲),生产环境同源无需前缀
156
+ const SSE_BASE = import.meta.env.DEV ? 'http://localhost:7860' : '';
157
  const response = await fetch(`${SSE_BASE}/api/student/chat/${agentId}`, {
158
  method: 'POST',
159
  headers: {
frontend/vite.config.js CHANGED
@@ -4,6 +4,10 @@ import react from '@vitejs/plugin-react'
4
  // https://vite.dev/config/
5
  export default defineConfig({
6
  plugins: [react()],
 
 
 
 
7
  server: {
8
  port: 3000,
9
  proxy: {
 
4
  // https://vite.dev/config/
5
  export default defineConfig({
6
  plugins: [react()],
7
+ build: {
8
+ outDir: '../static/dist',
9
+ emptyOutDir: true,
10
+ },
11
  server: {
12
  port: 3000,
13
  proxy: {
modules/agent_builder/routes.py CHANGED
@@ -9,8 +9,9 @@ from config import STREAM_API_KEY, STREAM_BASE_URL, DEFAULT_MODEL
9
 
10
  agent_builder_bp = Blueprint('agent_builder', __name__)
11
 
12
- # 确保Agent存储目录存在
13
- AGENTS_DIR = 'agents'
 
14
  os.makedirs(AGENTS_DIR, exist_ok=True)
15
 
16
  @agent_builder_bp.route('/create', methods=['POST'])
 
9
 
10
  agent_builder_bp = Blueprint('agent_builder', __name__)
11
 
12
+ # 数据持久化目录(HuggingFace Spaces 用 /data,本地开发用当前目录)
13
+ DATA_DIR = os.getenv("DATA_DIR", ".")
14
+ AGENTS_DIR = os.path.join(DATA_DIR, "agents")
15
  os.makedirs(AGENTS_DIR, exist_ok=True)
16
 
17
  @agent_builder_bp.route('/create', methods=['POST'])
static/dist/assets/index-DKbje17l.js ADDED
The diff for this file is too large to render. See raw diff
 
static/dist/assets/index-D_3YlA2q.js ADDED
The diff for this file is too large to render. See raw diff
 
static/dist/assets/index-KecMWszE.js ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ import{g as mt,d as xt,H as yt,e as kt,w as M,n as X}from"./index-BaHY2QRW.js";import{l as Re}from"./index-BaHY2QRW.js";import{t as S,x as vt,y as _t,i as bt}from"./index-DKbje17l.js";class Z extends Map{constructor(t,e=zt){if(super(),Object.defineProperties(this,{_intern:{value:new Map},_key:{value:e}}),t!=null)for(const[n,r]of t)this.set(n,r)}get(t){return super.get(G(this,t))}has(t){return super.has(G(this,t))}set(t,e){return super.set(wt(this,t),e)}delete(t){return super.delete($t(this,t))}}function G({_intern:i,_key:t},e){const n=t(e);return i.has(n)?i.get(n):e}function wt({_intern:i,_key:t},e){const n=t(e);return i.has(n)?i.get(n):(i.set(n,e),e)}function $t({_intern:i,_key:t},e){const n=t(e);return i.has(n)&&(e=i.get(n),i.delete(n)),e}function zt(i){return i!==null&&typeof i=="object"?i.valueOf():i}function J(i,t){let e;if(t===void 0)for(const n of i)n!=null&&(e<n||e===void 0&&n>=n)&&(e=n);else{let n=-1;for(let r of i)(r=t(r,++n,i))!=null&&(e<r||e===void 0&&r>=r)&&(e=r)}return e}function Q(i,t){let e;if(t===void 0)for(const n of i)n!=null&&(e>n||e===void 0&&n>=n)&&(e=n);else{let n=-1;for(let r of i)(r=t(r,++n,i))!=null&&(e>r||e===void 0&&r>=r)&&(e=r)}return e}function Et(i,t){let e,n=-1,r=-1;if(t===void 0)for(const s of i)++r,s!=null&&(e>s||e===void 0&&s>=s)&&(e=s,n=r);else for(let s of i)(s=t(s,++r,i))!=null&&(e>s||e===void 0&&s>=s)&&(e=s,n=r);return n}const H=Math.PI,P=2*H,z=1e-6,Ct=P-z;function it(i){this._+=i[0];for(let t=1,e=i.length;t<e;++t)this._+=arguments[t]+i[t]}function St(i){let t=Math.floor(i);if(!(t>=0))throw new Error(`invalid digits: ${i}`);if(t>15)return it;const e=10**t;return function(n){this._+=n[0];for(let r=1,s=n.length;r<s;++r)this._+=Math.round(arguments[r]*e)/e+n[r]}}class Mt{constructor(t){this._x0=this._y0=this._x1=this._y1=null,this._="",this._append=t==null?it:St(t)}moveTo(t,e){this._append`M${this._x0=this._x1=+t},${this._y0=this._y1=+e}`}closePath(){this._x1!==null&&(this._x1=this._x0,this._y1=this._y0,this._append`Z`)}lineTo(t,e){this._append`L${this._x1=+t},${this._y1=+e}`}quadraticCurveTo(t,e,n,r){this._append`Q${+t},${+e},${this._x1=+n},${this._y1=+r}`}bezierCurveTo(t,e,n,r,s,l){this._append`C${+t},${+e},${+n},${+r},${this._x1=+s},${this._y1=+l}`}arcTo(t,e,n,r,s){if(t=+t,e=+e,n=+n,r=+r,s=+s,s<0)throw new Error(`negative radius: ${s}`);let l=this._x1,o=this._y1,h=n-t,d=r-e,c=l-t,u=o-e,f=c*c+u*u;if(this._x1===null)this._append`M${this._x1=t},${this._y1=e}`;else if(f>z)if(!(Math.abs(u*h-d*c)>z)||!s)this._append`L${this._x1=t},${this._y1=e}`;else{let g=n-l,m=r-o,x=h*h+d*d,k=g*g+m*m,v=Math.sqrt(x),b=Math.sqrt(f),C=s*Math.tan((H-Math.acos((x+f-k)/(2*v*b)))/2),w=C/b,$=C/v;Math.abs(w-1)>z&&this._append`L${t+w*c},${e+w*u}`,this._append`A${s},${s},0,0,${+(u*g>c*m)},${this._x1=t+$*h},${this._y1=e+$*d}`}}arc(t,e,n,r,s,l){if(t=+t,e=+e,n=+n,l=!!l,n<0)throw new Error(`negative radius: ${n}`);let o=n*Math.cos(r),h=n*Math.sin(r),d=t+o,c=e+h,u=1^l,f=l?r-s:s-r;this._x1===null?this._append`M${d},${c}`:(Math.abs(this._x1-d)>z||Math.abs(this._y1-c)>z)&&this._append`L${d},${c}`,n&&(f<0&&(f=f%P+P),f>Ct?this._append`A${n},${n},0,1,${u},${t-o},${e-h}A${n},${n},0,1,${u},${this._x1=d},${this._y1=c}`:f>z&&this._append`A${n},${n},0,${+(f>=H)},${u},${this._x1=t+n*Math.cos(s)},${this._y1=e+n*Math.sin(s)}`)}rect(t,e,n,r){this._append`M${this._x0=this._x1=+t},${this._y0=this._y1=+e}h${n=+n}v${+r}h${-n}Z`}toString(){return this._}}function Xt(i,t){switch(arguments.length){case 0:break;case 1:this.range(i);break;default:this.range(t).domain(i);break}return this}const U=Symbol("implicit");function nt(){var i=new Z,t=[],e=[],n=U;function r(s){let l=i.get(s);if(l===void 0){if(n!==U)return n;i.set(s,l=t.push(s)-1)}return e[l%e.length]}return r.domain=function(s){if(!arguments.length)return t.slice();t=[],i=new Z;for(const l of s)i.has(l)||i.set(l,t.push(l)-1);return r},r.range=function(s){return arguments.length?(e=Array.from(s),r):e.slice()},r.unknown=function(s){return arguments.length?(n=s,r):n},r.copy=function(){return nt(t,e).unknown(n)},Xt.apply(r,arguments),r}function At(i){for(var t=i.length/6|0,e=new Array(t),n=0;n<t;)e[n]="#"+i.slice(n*6,++n*6);return e}const Rt=At("1f77b4ff7f0e2ca02cd627289467bd8c564be377c27f7f7fbcbd2217becf");function tt(i){return function(){return i}}function jt(i){let t=3;return i.digits=function(e){if(!arguments.length)return t;if(e==null)t=null;else{const n=Math.floor(e);if(!(n>=0))throw new RangeError(`invalid digits: ${e}`);t=n}return i},()=>new Mt(t)}var Ot=Array.prototype.slice;function Tt(i){return i[0]}function Bt(i){return i[1]}class Ht{constructor(t,e){this._context=t,this._x=e}areaStart(){this._line=0}areaEnd(){this._line=NaN}lineStart(){this._point=0}lineEnd(){(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line}point(t,e){switch(t=+t,e=+e,this._point){case 0:{this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break}case 1:this._point=2;default:{this._x?this._context.bezierCurveTo(this._x0=(this._x0+t)/2,this._y0,this._x0,e,t,e):this._context.bezierCurveTo(this._x0,this._y0=(this._y0+e)/2,t,this._y0,t,e);break}}this._x0=t,this._y0=e}}function Pt(i){return new Ht(i,!0)}function Dt(i){return i.source}function Lt(i){return i.target}function Nt(i){let t=Dt,e=Lt,n=Tt,r=Bt,s=null,l=null,o=jt(h);function h(){let d;const c=Ot.call(arguments),u=t.apply(this,c),f=e.apply(this,c);if(s==null&&(l=i(d=o())),l.lineStart(),c[0]=u,l.point(+n.apply(this,c),+r.apply(this,c)),c[0]=f,l.point(+n.apply(this,c),+r.apply(this,c)),l.lineEnd(),d)return l=null,d+""||null}return h.source=function(d){return arguments.length?(t=d,h):t},h.target=function(d){return arguments.length?(e=d,h):e},h.x=function(d){return arguments.length?(n=typeof d=="function"?d:tt(+d),h):n},h.y=function(d){return arguments.length?(r=typeof d=="function"?d:tt(+d),h):r},h.context=function(d){return arguments.length?(d==null?s=l=null:l=i(s=d),h):s},h}function Ft(){return Nt(Pt)}const rt=typeof navigator<"u"&&navigator.userAgent.includes("Macintosh"),It=nt(Rt),Wt=(i=1,t=3,e=2)=>n=>i+t/e**n.state.depth,qt={autoFit:!1,duration:500,embedGlobalCSS:!0,fitRatio:.95,maxInitialScale:2,scrollForPan:rt,initialExpandLevel:-1,zoom:!0,pan:!0,toggleRecursively:!1,color:i=>{var t;return It(`${((t=i.state)==null?void 0:t.path)||""}`)},lineWidth:Wt(),maxWidth:0,nodeMinHeight:16,paddingX:8,spacingHorizontal:80,spacingVertical:5};function Kt(i){let t=0;for(let e=0;e<i.length;e++)t=(t<<5)-t+i.charCodeAt(e)|0;return(t>>>0).toString(36)}function _(i){if(typeof i=="string"){const e=i;i=n=>n.matches(e)}const t=i;return function(){let e=Array.from(this.childNodes);return t&&(e=e.filter(n=>t(n))),e}}function Vt(i){var t=0,e=i.children,n=e&&e.length;if(!n)t=1;else for(;--n>=0;)t+=e[n].value;i.value=t}function Yt(){return this.eachAfter(Vt)}function Zt(i){var t=this,e,n=[t],r,s,l;do for(e=n.reverse(),n=[];t=e.pop();)if(i(t),r=t.children,r)for(s=0,l=r.length;s<l;++s)n.push(r[s]);while(n.length);return this}function Gt(i){for(var t=this,e=[t],n,r;t=e.pop();)if(i(t),n=t.children,n)for(r=n.length-1;r>=0;--r)e.push(n[r]);return this}function Jt(i){for(var t=this,e=[t],n=[],r,s,l;t=e.pop();)if(n.push(t),r=t.children,r)for(s=0,l=r.length;s<l;++s)e.push(r[s]);for(;t=n.pop();)i(t);return this}function Qt(i){return this.eachAfter(function(t){for(var e=+i(t.data)||0,n=t.children,r=n&&n.length;--r>=0;)e+=n[r].value;t.value=e})}function Ut(i){return this.eachBefore(function(t){t.children&&t.children.sort(i)})}function te(i){for(var t=this,e=ee(t,i),n=[t];t!==e;)t=t.parent,n.push(t);for(var r=n.length;i!==e;)n.splice(r,0,i),i=i.parent;return n}function ee(i,t){if(i===t)return i;var e=i.ancestors(),n=t.ancestors(),r=null;for(i=e.pop(),t=n.pop();i===t;)r=i,i=e.pop(),t=n.pop();return r}function ie(){for(var i=this,t=[i];i=i.parent;)t.push(i);return t}function ne(){var i=[];return this.each(function(t){i.push(t)}),i}function re(){var i=[];return this.eachBefore(function(t){t.children||i.push(t)}),i}function ae(){var i=this,t=[];return i.each(function(e){e!==i&&t.push({source:e.parent,target:e})}),t}function D(i,t){var e=new A(i),n=+i.value&&(e.value=i.value),r,s=[e],l,o,h,d;for(t==null&&(t=oe);r=s.pop();)if(n&&(r.value=+r.data.value),(o=t(r.data))&&(d=o.length))for(r.children=new Array(d),h=d-1;h>=0;--h)s.push(l=r.children[h]=new A(o[h])),l.parent=r,l.depth=r.depth+1;return e.eachBefore(le)}function se(){return D(this).eachBefore(he)}function oe(i){return i.children}function he(i){i.data=i.data.data}function le(i){var t=0;do i.height=t;while((i=i.parent)&&i.height<++t)}function A(i){this.data=i,this.depth=this.height=0,this.parent=null}A.prototype=D.prototype={constructor:A,count:Yt,each:Zt,eachAfter:Jt,eachBefore:Gt,sum:Qt,sort:Ut,path:te,ancestors:ie,descendants:ne,leaves:re,links:ae,copy:se};const ce="2.1.2",de={version:ce},{version:ue}=de,pe=Object.freeze({children:i=>i.children,nodeSize:i=>i.data.size,spacing:0});function st(i){const t=Object.assign({},pe,i);function e(o){const h=t[o];return typeof h=="function"?h:()=>h}function n(o){const h=l(s(),o,d=>d.children);return h.update(),h.data}function r(){const o=e("nodeSize"),h=e("spacing");return class at extends D.prototype.constructor{constructor(c){super(c)}copy(){const c=l(this.constructor,this,u=>u.children);return c.each(u=>u.data=u.data.data),c}get size(){return o(this)}spacing(c){return h(this,c)}get nodes(){return this.descendants()}get xSize(){return this.size[0]}get ySize(){return this.size[1]}get top(){return this.y}get bottom(){return this.y+this.ySize}get left(){return this.x-this.xSize/2}get right(){return this.x+this.xSize/2}get root(){const c=this.ancestors();return c[c.length-1]}get numChildren(){return this.hasChildren?this.children.length:0}get hasChildren(){return!this.noChildren}get noChildren(){return this.children===null}get firstChild(){return this.hasChildren?this.children[0]:null}get lastChild(){return this.hasChildren?this.children[this.numChildren-1]:null}get extents(){return(this.children||[]).reduce((c,u)=>at.maxExtents(c,u.extents),this.nodeExtents)}get nodeExtents(){return{top:this.top,bottom:this.bottom,left:this.left,right:this.right}}static maxExtents(c,u){return{top:Math.min(c.top,u.top),bottom:Math.max(c.bottom,u.bottom),left:Math.min(c.left,u.left),right:Math.max(c.right,u.right)}}}}function s(){const o=r(),h=e("nodeSize"),d=e("spacing");return class extends o{constructor(c){super(c),Object.assign(this,{x:0,y:0,relX:0,prelim:0,shift:0,change:0,lExt:this,lExtRelX:0,lThr:null,rExt:this,rExtRelX:0,rThr:null})}get size(){return h(this.data)}spacing(c){return d(this.data,c.data)}get x(){return this.data.x}set x(c){this.data.x=c}get y(){return this.data.y}set y(c){this.data.y=c}update(){return ot(this),ht(this),this}}}function l(o,h,d){const c=(u,f)=>{const g=new o(u);Object.assign(g,{parent:f,depth:f===null?0:f.depth+1,height:0,length:1});const m=d(u)||[];return g.children=m.length===0?null:m.map(x=>c(x,g)),g.children&&Object.assign(g,g.children.reduce((x,k)=>({height:Math.max(x.height,k.height+1),length:x.length+k.length}),g)),g};return c(h,null)}return Object.assign(n,{nodeSize(o){return arguments.length?(t.nodeSize=o,n):t.nodeSize},spacing(o){return arguments.length?(t.spacing=o,n):t.spacing},children(o){return arguments.length?(t.children=o,n):t.children},hierarchy(o,h){const d=typeof h>"u"?t.children:h;return l(r(),o,d)},dump(o){const h=e("nodeSize"),d=c=>u=>{const f=c+" ",g=c+" ",{x:m,y:x}=u,k=h(u),v=u.children||[],b=v.length===0?" ":`,${f}children: [${g}${v.map(d(g)).join(g)}${f}],${c}`;return`{ size: [${k.join(", ")}],${f}x: ${m}, y: ${x}${b}},`};return d(`
2
+ `)(o)}}),n}st.version=ue;const ot=(i,t=0)=>(i.y=t,(i.children||[]).reduce((e,n)=>{const[r,s]=e;ot(n,i.y+i.ySize);const l=(r===0?n.lExt:n.rExt).bottom;r!==0&&ge(i,r,s);const o=we(l,r,s);return[r+1,o]},[0,null]),fe(i),be(i),i),ht=(i,t,e)=>{typeof t>"u"&&(t=-i.relX-i.prelim,e=0);const n=t+i.relX;return i.relX=n+i.prelim-e,i.prelim=0,i.x=e+i.relX,(i.children||[]).forEach(r=>ht(r,n,i.x)),i},fe=i=>{(i.children||[]).reduce((t,e)=>{const[n,r]=t,s=n+e.shift,l=r+s+e.change;return e.relX+=l,[s,l]},[0,0])},ge=(i,t,e)=>{const n=i.children[t-1],r=i.children[t];let s=n,l=n.relX,o=r,h=r.relX,d=!0;for(;s&&o;){s.bottom>e.lowY&&(e=e.next);const c=l+s.prelim-(h+o.prelim)+s.xSize/2+o.xSize/2+s.spacing(o);(c>0||c<0&&d)&&(h+=c,me(r,c),xe(i,t,e.index,c)),d=!1;const u=s.bottom,f=o.bottom;u<=f&&(s=ke(s),s&&(l+=s.relX)),u>=f&&(o=ye(o),o&&(h+=o.relX))}!s&&o?ve(i,t,o,h):s&&!o&&_e(i,t,s,l)},me=(i,t)=>{i.relX+=t,i.lExtRelX+=t,i.rExtRelX+=t},xe=(i,t,e,n)=>{const r=i.children[t],s=t-e;if(s>1){const l=n/s;i.children[e+1].shift+=l,r.shift-=l,r.change-=n-l}},ye=i=>i.hasChildren?i.firstChild:i.lThr,ke=i=>i.hasChildren?i.lastChild:i.rThr,ve=(i,t,e,n)=>{const r=i.firstChild,s=r.lExt,l=i.children[t];s.lThr=e;const o=n-e.relX-r.lExtRelX;s.relX+=o,s.prelim-=o,r.lExt=l.lExt,r.lExtRelX=l.lExtRelX},_e=(i,t,e,n)=>{const r=i.children[t],s=r.rExt,l=i.children[t-1];s.rThr=e;const o=n-e.relX-r.rExtRelX;s.relX+=o,s.prelim-=o,r.rExt=l.rExt,r.rExtRelX=l.rExtRelX},be=i=>{if(i.hasChildren){const t=i.firstChild,e=i.lastChild,n=(t.prelim+t.relX-t.xSize/2+e.relX+e.prelim+e.xSize/2)/2;Object.assign(i,{prelim:n,lExt:t.lExt,lExtRelX:t.lExtRelX,rExt:e.rExt,rExtRelX:e.rExtRelX})}},we=(i,t,e)=>{for(;e!==null&&i>=e.lowY;)e=e.next;return{lowY:i,index:t,next:e}},$e=".markmap{--markmap-max-width: 9999px;--markmap-a-color: #0097e6;--markmap-a-hover-color: #00a8ff;--markmap-code-bg: #f0f0f0;--markmap-code-color: #555;--markmap-highlight-bg: #ffeaa7;--markmap-table-border: 1px solid currentColor;--markmap-font: 300 16px/20px sans-serif;--markmap-circle-open-bg: #fff;--markmap-text-color: #333;--markmap-highlight-node-bg: #ff02;font:var(--markmap-font);color:var(--markmap-text-color)}.markmap-link{fill:none}.markmap-node>circle{cursor:pointer}.markmap-foreign{display:inline-block}.markmap-foreign p{margin:0}.markmap-foreign a{color:var(--markmap-a-color)}.markmap-foreign a:hover{color:var(--markmap-a-hover-color)}.markmap-foreign code{padding:.25em;font-size:calc(1em - 2px);color:var(--markmap-code-color);background-color:var(--markmap-code-bg);border-radius:2px}.markmap-foreign pre{margin:0}.markmap-foreign pre>code{display:block}.markmap-foreign del{text-decoration:line-through}.markmap-foreign em{font-style:italic}.markmap-foreign strong{font-weight:700}.markmap-foreign mark{background:var(--markmap-highlight-bg)}.markmap-foreign table,.markmap-foreign th,.markmap-foreign td{border-collapse:collapse;border:var(--markmap-table-border)}.markmap-foreign img{display:inline-block}.markmap-foreign svg{fill:currentColor}.markmap-foreign>div{width:var(--markmap-max-width);text-align:left}.markmap-foreign>div>div{display:inline-block}.markmap-highlight rect{fill:var(--markmap-highlight-node-bg)}.markmap-dark .markmap{--markmap-code-bg: #1a1b26;--markmap-code-color: #ddd;--markmap-circle-open-bg: #444;--markmap-text-color: #eee}",O="g.markmap-node",ze="path.markmap-link",Ee="g.markmap-highlight",T=Ft();function et(i,t){const e=Et(i,t);return i[e]}function B(i){i.stopPropagation()}const Ce=new yt;class lt{constructor(t,e){this.options={...qt},this._disposeList=[],this.handleZoom=n=>{const{transform:r}=n;this.g.attr("transform",r)},this.handlePan=n=>{n.preventDefault();const r=S(this.svg.node()),s=r.translate(-n.deltaX/r.k,-n.deltaY/r.k);this.svg.call(this.zoom.transform,s)},this.handleClick=(n,r)=>{let s=this.options.toggleRecursively;(rt?n.metaKey:n.ctrlKey)&&(s=!s),this.toggleNode(r,s)},this.ensureView=this.ensureVisible,this.svg=t.datum?t:vt(t),this.styleNode=this.svg.append("style"),this.zoom=_t().filter(n=>this.options.scrollForPan&&n.type==="wheel"?n.ctrlKey&&!n.button:(!n.ctrlKey||n.type==="wheel")&&!n.button).on("zoom",this.handleZoom),this.setOptions(e),this.state={id:this.options.id||this.svg.attr("id")||mt(),rect:{x1:0,y1:0,x2:0,y2:0}},this.g=this.svg.append("g"),this.g.append("g").attr("class","markmap-highlight"),this._observer=new ResizeObserver(xt(()=>{this.renderData()},100)),this._disposeList.push(Ce.tap(()=>{this.setData()}),()=>this._observer.disconnect())}getStyleContent(){const{style:t}=this.options,{id:e}=this.state,n=typeof t=="function"?t(e):"";return[this.options.embedGlobalCSS&&$e,n].filter(Boolean).join(`
3
+ `)}updateStyle(){this.svg.attr("class",kt(this.svg.attr("class"),"markmap",this.state.id));const t=this.getStyleContent();this.styleNode.text(t)}async toggleNode(t,e=!1){var n,r;const s=(n=t.payload)!=null&&n.fold?0:1;e?M(t,(l,o)=>{l.payload={...l.payload,fold:s},o()}):t.payload={...t.payload,fold:(r=t.payload)!=null&&r.fold?0:1},await this.renderData(t)}_initializeData(t){let e=0;const{color:n,initialExpandLevel:r}=this.options;let s=0,l=0;return M(t,(o,h,d)=>{var c,u,f,g;l+=1,o.children=(c=o.children)==null?void 0:c.map(x=>({...x})),e+=1,o.state={...o.state,depth:l,id:e,rect:{x:0,y:0,width:0,height:0},size:[0,0]},o.state.key=[(u=d?.state)==null?void 0:u.id,o.state.id].filter(Boolean).join(".")+Kt(o.content),o.state.path=[(f=d?.state)==null?void 0:f.path,o.state.id].filter(Boolean).join("."),n(o);const m=((g=o.payload)==null?void 0:g.fold)===2;m?s+=1:(s||r>=0&&o.state.depth>=r)&&(o.payload={...o.payload,fold:1}),h(),m&&(s-=1),l-=1}),t}_relayout(){if(!this.state.data)return;this.g.selectAll(_(O)).selectAll(_("foreignObject")).each(function(h){var d;const c=(d=this.firstChild)==null?void 0:d.firstChild,u=[c.scrollWidth,c.scrollHeight];h.state.size=u});const{lineWidth:t,paddingX:e,spacingHorizontal:n,spacingVertical:r}=this.options,s=st({}).children(h=>{var d;if(!((d=h.payload)!=null&&d.fold))return h.children}).nodeSize(h=>{const[d,c]=h.data.state.size;return[c,d+(d?e*2:0)+n]}).spacing((h,d)=>(h.parent===d.parent?r:r*2)+t(h.data)),l=s.hierarchy(this.state.data);s(l);const o=l.descendants();o.forEach(h=>{const d=h.data;d.state.rect={x:h.y,y:h.x-h.xSize/2,width:h.ySize-n,height:h.xSize}}),this.state.rect={x1:Q(o,h=>h.data.state.rect.x)||0,y1:Q(o,h=>h.data.state.rect.y)||0,x2:J(o,h=>h.data.state.rect.x+h.data.state.rect.width)||0,y2:J(o,h=>h.data.state.rect.y+h.data.state.rect.height)||0}}setOptions(t){this.options={...this.options,...t},this.options.zoom?this.svg.call(this.zoom):this.svg.on(".zoom",null),this.options.pan?this.svg.on("wheel",this.handlePan):this.svg.on("wheel",null)}async setData(t,e){e&&this.setOptions(e),t&&(this.state.data=this._initializeData(t)),this.state.data&&(this.updateStyle(),await this.renderData())}async setHighlight(t){this.state.highlight=t||void 0,await this.renderData()}_getHighlightRect(t){const e=this.svg.node(),n=4/S(e).k,r={...t.state.rect};return r.x-=n,r.y-=n,r.width+=2*n,r.height+=2*n,r}async renderData(t){const{paddingX:e,autoFit:n,color:r,maxWidth:s,lineWidth:l}=this.options,o=this.state.data;if(!o)return;const h={},d={},c=[];M(o,(a,p,y)=>{var E;(E=a.payload)!=null&&E.fold||p(),h[a.state.id]=a,y&&(d[a.state.id]=y.state.id),c.push(a)});const u={},f={},g=a=>{!a||u[a.state.id]||M(a,(p,y)=>{u[p.state.id]=a.state.id,y()})},m=a=>f[u[a.state.id]]||o.state.rect,x=a=>(h[u[a.state.id]]||o).state.rect;f[o.state.id]=o.state.rect,t&&g(t);let{highlight:k}=this.state;k&&!h[k.state.id]&&(k=void 0);let v=this.g.selectAll(_(Ee)).selectAll(_("rect")).data(k?[this._getHighlightRect(k)]:[]).join("rect").attr("x",a=>a.x).attr("y",a=>a.y).attr("width",a=>a.width).attr("height",a=>a.height);const b=this.g.selectAll(_(O)).each(a=>{f[a.state.id]=a.state.rect}).data(c,a=>a.state.key),C=b.enter().append("g").attr("data-depth",a=>a.state.depth).attr("data-path",a=>a.state.path).each(a=>{g(h[d[a.state.id]])}),w=b.exit().each(a=>{g(h[d[a.state.id]])}),$=b.merge(C).attr("class",a=>{var p;return["markmap-node",((p=a.payload)==null?void 0:p.fold)&&"markmap-fold"].filter(Boolean).join(" ")}),L=$.selectAll(_("line")).data(a=>[a],a=>a.state.key),N=L.enter().append("line").attr("stroke",a=>r(a)).attr("stroke-width",0),F=L.merge(N),I=$.selectAll(_("circle")).data(a=>{var p;return(p=a.children)!=null&&p.length?[a]:[]},a=>a.state.key),W=I.enter().append("circle").attr("stroke-width",0).attr("r",0).on("click",(a,p)=>this.handleClick(a,p)).on("mousedown",B).merge(I).attr("stroke",a=>r(a)).attr("fill",a=>{var p;return(p=a.payload)!=null&&p.fold&&a.children?r(a):"var(--markmap-circle-open-bg)"}),q=this._observer,K=$.selectAll(_("foreignObject")).data(a=>[a],a=>a.state.key),R=K.enter().append("foreignObject").attr("class","markmap-foreign").attr("x",e).attr("y",0).style("opacity",0).on("mousedown",B).on("dblclick",B);R.append("xhtml:div").append("xhtml:div").html(a=>a.content).attr("xmlns","http://www.w3.org/1999/xhtml"),R.each(function(){var a;const p=(a=this.firstChild)==null?void 0:a.firstChild;q.observe(p)});const V=w.selectAll(_("foreignObject"));V.each(function(){var a;const p=(a=this.firstChild)==null?void 0:a.firstChild;q.unobserve(p)});const Y=R.merge(K),ct=c.flatMap(a=>{var p;return(p=a.payload)!=null&&p.fold?[]:a.children.map(y=>({source:a,target:y}))}),j=this.g.selectAll(_(ze)).data(ct,a=>a.target.state.key),dt=j.exit(),ut=j.enter().insert("path","g").attr("class","markmap-link").attr("data-depth",a=>a.target.state.depth).attr("data-path",a=>a.target.state.path).attr("d",a=>{const p=m(a.target),y=[p.x+p.width,p.y+p.height];return T({source:y,target:y})}).attr("stroke-width",0).merge(j);this.svg.style("--markmap-max-width",s?`${s}px`:null),await new Promise(requestAnimationFrame),this._relayout(),v=v.data(k?[this._getHighlightRect(k)]:[]).join("rect"),this.transition(v).attr("x",a=>a.x).attr("y",a=>a.y).attr("width",a=>a.width).attr("height",a=>a.height),C.attr("transform",a=>{const p=m(a);return`translate(${p.x+p.width-a.state.rect.width},${p.y+p.height-a.state.rect.height})`}),this.transition(w).attr("transform",a=>{const p=x(a),y=p.x+p.width-a.state.rect.width,E=p.y+p.height-a.state.rect.height;return`translate(${y},${E})`}).remove(),this.transition($).attr("transform",a=>`translate(${a.state.rect.x},${a.state.rect.y})`);const pt=w.selectAll(_("line"));this.transition(pt).attr("x1",a=>a.state.rect.width).attr("stroke-width",0),N.attr("x1",a=>a.state.rect.width).attr("x2",a=>a.state.rect.width),F.attr("y1",a=>a.state.rect.height+l(a)/2).attr("y2",a=>a.state.rect.height+l(a)/2),this.transition(F).attr("x1",-1).attr("x2",a=>a.state.rect.width+2).attr("stroke",a=>r(a)).attr("stroke-width",l);const ft=w.selectAll(_("circle"));this.transition(ft).attr("r",0).attr("stroke-width",0),W.attr("cx",a=>a.state.rect.width).attr("cy",a=>a.state.rect.height+l(a)/2),this.transition(W).attr("r",6).attr("stroke-width","1.5"),this.transition(V).style("opacity",0),Y.attr("width",a=>Math.max(0,a.state.rect.width-e*2)).attr("height",a=>a.state.rect.height),this.transition(Y).style("opacity",1),this.transition(dt).attr("d",a=>{const p=x(a.target),y=[p.x+p.width,p.y+p.height+l(a.target)/2];return T({source:y,target:y})}).attr("stroke-width",0).remove(),this.transition(ut).attr("stroke",a=>r(a.target)).attr("stroke-width",a=>l(a.target)).attr("d",a=>{const p=a.source,y=a.target,E=[p.state.rect.x+p.state.rect.width,p.state.rect.y+p.state.rect.height+l(p)/2],gt=[y.state.rect.x,y.state.rect.y+y.state.rect.height+l(y)/2];return T({source:E,target:gt})}),n&&this.fit()}transition(t){const{duration:e}=this.options;return t.transition().duration(e)}async fit(t=this.options.maxInitialScale){const e=this.svg.node(),{width:n,height:r}=e.getBoundingClientRect(),{fitRatio:s}=this.options,{x1:l,y1:o,x2:h,y2:d}=this.state.rect,c=h-l,u=d-o,f=Math.min(n/c*s,r/u*s,t),g=bt.translate((n-c*f)/2-l*f,(r-u*f)/2-o*f).scale(f);return this.transition(this.svg).call(this.zoom.transform,g).end().catch(X)}findElement(t){let e;return this.g.selectAll(_(O)).each(function(n){n===t&&(e={data:n,g:this})}),e}async ensureVisible(t,e){var n;const r=(n=this.findElement(t))==null?void 0:n.data;if(!r)return;const s=this.svg.node(),l=s.getBoundingClientRect(),o=S(s),[h,d]=[r.state.rect.x,r.state.rect.x+r.state.rect.width+2].map(v=>v*o.k+o.x),[c,u]=[r.state.rect.y,r.state.rect.y+r.state.rect.height].map(v=>v*o.k+o.y),f={left:0,right:0,top:0,bottom:0,...e},g=[f.left-h,l.width-f.right-d],m=[f.top-c,l.height-f.bottom-u],x=g[0]*g[1]>0?et(g,Math.abs)/o.k:0,k=m[0]*m[1]>0?et(m,Math.abs)/o.k:0;if(x||k){const v=o.translate(x,k);return this.transition(this.svg).call(this.zoom.transform,v).end().catch(X)}}async centerNode(t,e){var n;const r=(n=this.findElement(t))==null?void 0:n.data;if(!r)return;const s=this.svg.node(),l=s.getBoundingClientRect(),o=S(s),h=(r.state.rect.x+r.state.rect.width/2)*o.k+o.x,d=(r.state.rect.y+r.state.rect.height/2)*o.k+o.y,c={left:0,right:0,top:0,bottom:0,...e},u=(c.left+l.width-c.right)/2,f=(c.top+l.height-c.bottom)/2,g=(u-h)/o.k,m=(f-d)/o.k;if(g||m){const x=o.translate(g,m);return this.transition(this.svg).call(this.zoom.transform,x).end().catch(X)}}async rescale(t){const e=this.svg.node(),{width:n,height:r}=e.getBoundingClientRect(),s=n/2,l=r/2,o=S(e),h=o.translate((s-o.x)*(1-t)/o.k,(l-o.y)*(1-t)/o.k).scale(t);return this.transition(this.svg).call(this.zoom.transform,h).end().catch(X)}destroy(){this.svg.on(".zoom",null),this.svg.html(null),this._disposeList.forEach(t=>{t()})}static create(t,e,n=null){const r=new lt(t,e);return n&&r.setData(n).then(()=>{r.fit()}),r}}export{lt as Markmap,_ as childSelector,It as defaultColorFn,qt as defaultOptions,rt as isMacintosh,Wt as lineWidthFactory,Re as loadJS,Ce as refreshHook,Kt as simpleHash};
static/dist/index.html CHANGED
@@ -5,7 +5,7 @@
5
  <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
  <title>frontend</title>
8
- <script type="module" crossorigin src="/assets/index-BXTNupnb.js"></script>
9
  <link rel="stylesheet" crossorigin href="/assets/index-DJrkXzw_.css">
10
  </head>
11
  <body>
 
5
  <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
  <title>frontend</title>
8
+ <script type="module" crossorigin src="/assets/index-DKbje17l.js"></script>
9
  <link rel="stylesheet" crossorigin href="/assets/index-DJrkXzw_.css">
10
  </head>
11
  <body>
utils/helpers.py CHANGED
@@ -18,7 +18,8 @@ def create_response(success, message="", data=None, status_code=200):
18
 
19
  def validate_agent_access(agent_id, token=None):
20
  """验证Agent访问权限"""
21
- agent_path = os.path.join('agents', f"{agent_id}.json")
 
22
 
23
  if not os.path.exists(agent_path):
24
  return False, "Agent不存在"
 
18
 
19
  def validate_agent_access(agent_id, token=None):
20
  """验证Agent访问权限"""
21
+ DATA_DIR = os.getenv("DATA_DIR", ".")
22
+ agent_path = os.path.join(DATA_DIR, "agents", f"{agent_id}.json")
23
 
24
  if not os.path.exists(agent_path):
25
  return False, "Agent不存在"