chore: 批量新增各类工具脚本与配置文件
1. 新增音频录制、下载、上传相关脚本 2. 新增数据库操作、API调用工具 3. 新增Excel数据处理脚本 4. 新增弱密码检测脚本
This commit is contained in:
+114
@@ -0,0 +1,114 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"id": "fee9c5bf",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"401\n",
|
||||
"{'code': 'INVALID_API_KEY', 'message': 'Invalid API key'}\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import requests\n",
|
||||
"\n",
|
||||
"base_url = \"https://console.pivotbak.cfd/v1\"\n",
|
||||
"api_key = \"sk-e5246cf15eed1c8c1b94f172c95115de3ae5413eaa5b0366810fa7842de6ada1\"\n",
|
||||
"\n",
|
||||
"resp = requests.get(\n",
|
||||
" f\"{base_url}/models\",\n",
|
||||
" headers={\n",
|
||||
" \"Authorization\": f\"Bearer {api_key}\",\n",
|
||||
" \"Content-Type\": \"application/json\",\n",
|
||||
" },\n",
|
||||
" timeout=30,\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"print(resp.status_code)\n",
|
||||
"print(resp.json())"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 11,
|
||||
"id": "c479e82c",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"ename": "ModuleNotFoundError",
|
||||
"evalue": "No module named 'curl_cffi'",
|
||||
"output_type": "error",
|
||||
"traceback": [
|
||||
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
|
||||
"\u001b[1;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)",
|
||||
"Cell \u001b[1;32mIn[11], line 2\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mos\u001b[39;00m\n\u001b[1;32m----> 2\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mcurl_cffi\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m requests\n\u001b[0;32m 4\u001b[0m BASE_URL \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mhttps://console.pivotbak.cfd/v1\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 5\u001b[0m API_KEY \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124msk-e5246cf15eed1c8c1b94f172c95115de3ae5413eaa5b0366810fa7842de6ada1\u001b[39m\u001b[38;5;124m\"\u001b[39m\n",
|
||||
"\u001b[1;31mModuleNotFoundError\u001b[0m: No module named 'curl_cffi'"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"from curl_cffi import requests\n",
|
||||
"\n",
|
||||
"BASE_URL = \"https://console.pivotbak.cfd/v1\"\n",
|
||||
"API_KEY = \"sk-e5246cf15eed1c8c1b94f172c95115de3ae5413eaa5b0366810fa7842de6ada1\"\n",
|
||||
"\n",
|
||||
"headers = {\n",
|
||||
" \"Authorization\": f\"Bearer {API_KEY}\",\n",
|
||||
" \"x-api-key\": API_KEY,\n",
|
||||
" \"Accept\": \"*/*\",\n",
|
||||
" \"Content-Type\": \"application/json\",\n",
|
||||
" \"sec-ch-ua-platform\": '\"Windows\"',\n",
|
||||
" \"sec-ch-ua\": '\"Not-A.Brand\";v=\"24\", \"Chromium\";v=\"146\"',\n",
|
||||
" \"sec-ch-ua-mobile\": \"?0\",\n",
|
||||
" \"x-title\": \"Cherry Studio\",\n",
|
||||
" \"User-Agent\": \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) CherryStudio/1.9.9 Chrome/146.0.7680.188 Electron/41.2.1 Safari/537.36\",\n",
|
||||
" \"HTTP-Referer\": \"https://cherry-ai.com\",\n",
|
||||
" \"Sec-Fetch-Site\": \"cross-site\",\n",
|
||||
" \"Sec-Fetch-Mode\": \"cors\",\n",
|
||||
" \"Sec-Fetch-Dest\": \"empty\",\n",
|
||||
" \"Accept-Encoding\": \"gzip, deflate, br, zstd\",\n",
|
||||
" \"Accept-Language\": \"zh-CN\",\n",
|
||||
" \"Priority\": \"u=1, i\",\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"resp = requests.get(\n",
|
||||
" f\"{BASE_URL}/models\",\n",
|
||||
" headers=headers,\n",
|
||||
" impersonate=\"chrome136\",\n",
|
||||
" timeout=30,\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"print(\"status:\", resp.status_code)\n",
|
||||
"print(resp.text)"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "base",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.12.4"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
+208
File diff suppressed because one or more lines are too long
@@ -0,0 +1,30 @@
|
||||
"input": "最近一次考试是什么?",
|
||||
"input": "最近一次数学考试的成绩情况",
|
||||
"input": "最近一次英语考试各班考得怎么样",
|
||||
"input": "最近一次语文考试全年级的平均分",
|
||||
"input": "最近一次考试是谁发布的?",
|
||||
"input": "帮我查一下期中相关的成绩批次",
|
||||
"input": "帮我看看最近一次数学考试的数据结构",
|
||||
"input": "帮我分析最近一次数学考试各班成绩情况",
|
||||
"input": "帮我看看最近一次数学考试整个年级的成绩概况",
|
||||
"input": "帮我分析最近一次数学考试的分数分布情况",
|
||||
"input": "帮我对比分析最近一次考试语文数学英语三个科目的成绩情况",
|
||||
"input": "帮我查一下白若耶是哪位学生",
|
||||
"input": "帮我看看白若耶最近整体成绩怎么样",
|
||||
"input": "把白若耶最近几次数学成绩列出来",
|
||||
"input": "白若耶最近10次数学考试的成绩趋势怎么样",
|
||||
"input": "只分析语文数学英语这三科,帮我看白若耶哪科强哪科弱",
|
||||
"input": "只看语文数学英语三科,白若耶偏科吗?",
|
||||
"input": "白若耶最近有没有退步预警?",
|
||||
"input": "帮我看看白若耶最近一次考试的成绩详情",
|
||||
"input": "先给我看看趋势分析有哪些可用参数和批次",
|
||||
"input": "帮我看一班最近几次数学考试的均分走势",
|
||||
"input": "帮我看最近几次数学考试整体均分变化",
|
||||
"input": "白若耶这次考试比上次是进步还是退步?",
|
||||
"input": "白若耶最近一次考试排第几名?",
|
||||
"input": "最近一次数学考试分段分析有哪些可用配置?",
|
||||
"input": "帮我看最近一次数学考试各分段人数分布",
|
||||
"input": "帮我看最近一次数学考试高分段有哪些学生",
|
||||
"input": "帮我比较最近两次数学考试各分数段人数变化",
|
||||
"input": "帮我对比分析语文数学英语三个科目在不同批次的成绩情况,按班级分组",
|
||||
"input": "帮我对比分析白若耶在语文数学英语三个科目的跨批次成绩"
|
||||
+184
@@ -0,0 +1,184 @@
|
||||
const BASE_URL = process.env.LANGGRAPH_URL || "http://192.168.0.100:2026";
|
||||
const ASSISTANT_ID = process.env.ASSISTANT_ID || "student_score";
|
||||
const QUESTION = process.env.QUESTION || "白若耶最近10次数学考试的成绩趋势怎么样";
|
||||
|
||||
const CONTEXT = {
|
||||
team_id: process.env.TEAM_ID || "19",
|
||||
env: process.env.AGENT_ENV || "dev",
|
||||
};
|
||||
|
||||
function parseJson(text) {
|
||||
try {
|
||||
return JSON.parse(text);
|
||||
} catch {
|
||||
return text;
|
||||
}
|
||||
}
|
||||
|
||||
async function createThread() {
|
||||
const response = await fetch(`${BASE_URL}/threads`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({}),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`create thread failed: ${response.status} ${await response.text()}`);
|
||||
}
|
||||
|
||||
const thread = await response.json();
|
||||
return thread.thread_id;
|
||||
}
|
||||
|
||||
function pickFinalAnswer(data) {
|
||||
if (!data || typeof data !== "object" || Array.isArray(data)) {
|
||||
return "";
|
||||
}
|
||||
|
||||
const renderAnswer = data.render_answer;
|
||||
if (renderAnswer && typeof renderAnswer.answer === "string") {
|
||||
return renderAnswer.answer;
|
||||
}
|
||||
|
||||
if (typeof data.answer === "string") {
|
||||
return data.answer;
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
function pickReasoning(data) {
|
||||
if (!data || typeof data !== "object" || Array.isArray(data)) {
|
||||
return "";
|
||||
}
|
||||
|
||||
const renderAnswer = data.render_answer;
|
||||
if (renderAnswer && typeof renderAnswer.reasoning === "string") {
|
||||
return renderAnswer.reasoning;
|
||||
}
|
||||
|
||||
if (typeof data.reasoning === "string") {
|
||||
return data.reasoning;
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
function handleEvent(eventName, dataText, answerParts, finalAnswers) {
|
||||
const data = parseJson(dataText);
|
||||
|
||||
if (eventName === "updates") {
|
||||
const finalAnswer = pickFinalAnswer(data);
|
||||
const reasoning = pickReasoning(data);
|
||||
if (data && typeof data === "object" && !Array.isArray(data)) {
|
||||
console.log(`\n[updates] ${Object.keys(data).join(", ")}`);
|
||||
} else {
|
||||
console.log("\n[updates]", data);
|
||||
}
|
||||
if (reasoning) {
|
||||
console.log("\n[reasoning]");
|
||||
console.log(reasoning);
|
||||
}
|
||||
if (finalAnswer) {
|
||||
finalAnswers.push(finalAnswer);
|
||||
console.log("\n[final.answer]");
|
||||
console.log(finalAnswer);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (eventName === "messages") {
|
||||
const messageChunk = Array.isArray(data) ? data[0] : undefined;
|
||||
const content = messageChunk && typeof messageChunk.content === "string" ? messageChunk.content : "";
|
||||
if (content) {
|
||||
answerParts.push(content);
|
||||
process.stdout.write(content);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (eventName) {
|
||||
console.log(`\n[${eventName}]`, data);
|
||||
}
|
||||
}
|
||||
|
||||
async function readSse(response) {
|
||||
if (!response.body) {
|
||||
throw new Error("response body is empty");
|
||||
}
|
||||
|
||||
const reader = response.body.getReader();
|
||||
const decoder = new TextDecoder("utf-8");
|
||||
const answerParts = [];
|
||||
const finalAnswers = [];
|
||||
let buffer = "";
|
||||
|
||||
while (true) {
|
||||
const { value, done } = await reader.read();
|
||||
if (done) break;
|
||||
|
||||
buffer += decoder.decode(value, { stream: true });
|
||||
const events = buffer.split(/\r?\n\r?\n/);
|
||||
buffer = events.pop() || "";
|
||||
|
||||
for (const rawEvent of events) {
|
||||
let eventName = "";
|
||||
const dataLines = [];
|
||||
|
||||
for (const line of rawEvent.split(/\r?\n/)) {
|
||||
if (line.startsWith("event:")) {
|
||||
eventName = line.slice("event:".length).trim();
|
||||
} else if (line.startsWith("data:")) {
|
||||
dataLines.push(line.slice("data:".length).trimStart());
|
||||
}
|
||||
}
|
||||
|
||||
handleEvent(eventName, dataLines.join("\n"), answerParts, finalAnswers);
|
||||
}
|
||||
}
|
||||
|
||||
if (buffer.trim()) {
|
||||
handleEvent("", buffer.trim(), answerParts, finalAnswers);
|
||||
}
|
||||
|
||||
return finalAnswers.at(-1) || answerParts.join("");
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const threadId = await createThread();
|
||||
const endpoint = `${BASE_URL}/threads/${threadId}/runs/stream`;
|
||||
const started = Date.now();
|
||||
|
||||
console.log("=== LangGraph fetch stream test ===");
|
||||
console.log(`base_url: ${BASE_URL}`);
|
||||
console.log(`assistant_id: ${ASSISTANT_ID}`);
|
||||
console.log(`thread_id: ${threadId}`);
|
||||
console.log("");
|
||||
|
||||
const response = await fetch(endpoint, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Accept: "text/event-stream",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
assistant_id: ASSISTANT_ID,
|
||||
input: { question: QUESTION },
|
||||
context: CONTEXT,
|
||||
stream_mode: ["updates", "messages-tuple"],
|
||||
}),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`stream request failed: ${response.status} ${await response.text()}`);
|
||||
}
|
||||
|
||||
const answer = await readSse(response);
|
||||
const elapsed = ((Date.now() - started) / 1000).toFixed(2);
|
||||
console.log(`\n\n=== done: ${elapsed}s, answer length: ${answer.length} ===`);
|
||||
}
|
||||
|
||||
main().catch((error) => {
|
||||
console.error(error);
|
||||
process.exitCode = 1;
|
||||
});
|
||||
+108
@@ -0,0 +1,108 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import os
|
||||
import sys
|
||||
from typing import Any
|
||||
|
||||
from langgraph_sdk import get_client
|
||||
|
||||
|
||||
BASE_URL = os.getenv("LANGGRAPH_URL", "http://192.168.0.100:2026")
|
||||
ASSISTANT_ID = "student_score"
|
||||
QUESTION = "帮我看看白若耶同学的信息"
|
||||
CONTEXT = {
|
||||
"team_id": "19",
|
||||
"env": "dev",
|
||||
}
|
||||
|
||||
|
||||
if hasattr(sys.stdout, "reconfigure"):
|
||||
sys.stdout.reconfigure(encoding="utf-8")
|
||||
|
||||
|
||||
def event_data(event: Any) -> Any:
|
||||
if isinstance(event, dict):
|
||||
return event.get("data")
|
||||
return getattr(event, "data", None)
|
||||
|
||||
|
||||
def event_name(event: Any) -> str:
|
||||
if isinstance(event, dict):
|
||||
return str(event.get("event") or "")
|
||||
return str(getattr(event, "event", ""))
|
||||
|
||||
|
||||
def pick_final_answer(data: Any) -> str:
|
||||
if not isinstance(data, dict):
|
||||
return ""
|
||||
render_answer = data.get("render_answer")
|
||||
if isinstance(render_answer, dict) and isinstance(render_answer.get("answer"), str):
|
||||
return render_answer["answer"]
|
||||
answer = data.get("answer")
|
||||
return answer if isinstance(answer, str) else ""
|
||||
|
||||
|
||||
def pick_answer_source(data: Any) -> str:
|
||||
if not isinstance(data, dict):
|
||||
return ""
|
||||
render_answer = data.get("render_answer")
|
||||
if isinstance(render_answer, dict) and isinstance(render_answer.get("answer_source"), str):
|
||||
return render_answer["answer_source"]
|
||||
answer_source = data.get("answer_source")
|
||||
return answer_source if isinstance(answer_source, str) else ""
|
||||
|
||||
|
||||
async def main() -> None:
|
||||
client = get_client(url=BASE_URL)
|
||||
thread = await client.threads.create()
|
||||
answer_parts: list[str] = []
|
||||
final_answers: list[str] = []
|
||||
|
||||
print("=== LangGraph updates + messages-tuple 流式调用 ===", flush=True)
|
||||
print("[updates] 节点进度;[messages] 最终 Markdown token。", flush=True)
|
||||
print("", flush=True)
|
||||
|
||||
async for event in client.runs.stream(
|
||||
thread_id=thread["thread_id"],
|
||||
assistant_id=ASSISTANT_ID,
|
||||
input={"question": QUESTION},
|
||||
context=CONTEXT,
|
||||
stream_mode=["updates", "messages-tuple"],
|
||||
):
|
||||
name = event_name(event)
|
||||
data = event_data(event)
|
||||
|
||||
if name == "updates":
|
||||
final_answer = pick_final_answer(data)
|
||||
answer_source = pick_answer_source(data)
|
||||
if isinstance(data, dict):
|
||||
print(f"\n[updates] {', '.join(data.keys())}", flush=True)
|
||||
render_answer = data.get("render_answer")
|
||||
if isinstance(render_answer, dict):
|
||||
print(f"[render_answer.keys] {', '.join(render_answer.keys())}", flush=True)
|
||||
else:
|
||||
print(f"\n[updates] {data}", flush=True)
|
||||
if answer_source:
|
||||
print(f"[answer_source] {answer_source}", flush=True)
|
||||
if final_answer:
|
||||
final_answers.append(final_answer)
|
||||
print("\n[final.answer]", flush=True)
|
||||
print(final_answer, flush=True)
|
||||
continue
|
||||
|
||||
if name == "messages":
|
||||
if isinstance(data, list) and data:
|
||||
message_chunk = data[0]
|
||||
content = message_chunk.get("content") if isinstance(message_chunk, dict) else ""
|
||||
if isinstance(content, str) and content:
|
||||
answer_parts.append(content)
|
||||
print(content, end="", flush=True)
|
||||
continue
|
||||
|
||||
print("\n\n=== 最终 Markdown 长度 ===", flush=True)
|
||||
print(len(final_answers[-1] if final_answers else "".join(answer_parts)), flush=True)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
Reference in New Issue
Block a user