首页 > 其他分享 >genaiscript踩坑:设置proxyman抓包、兼容qwen72b funtion-call

genaiscript踩坑:设置proxyman抓包、兼容qwen72b funtion-call

时间:2024-11-19 21:41:27浏览次数:1  
标签:... genaiscript proxyman call delta obj const

genaiscript有个很棒的日志系统,但是碰到接口报错就没用了,还是得抓包来看,为了设置proxy,得修改源码。genaiscript是通过npx运行的,包的执行优先顺序是本地依赖目录npm install genaiscript——npm全局依赖目录npm install -g genaiscript——npx缓存目录从没有安装过本地包,在Mac上对应的文件夹路径是 /你的本地项目/node_modules/genaiscript/built/genaiscript.cjs——/Users/username/.nvm/versions/node/v20.15.1/lib/node_modules/genaiscript/built/genaiscript.cjs——/Users/username/.npm/_npx/86ce7b375aee60ee/node_modules/genaiscript/built/genaiscript.cjs,注意如果运行npx --yes [email protected] run demo,如果你本地或者全局安装的版本不是@1.75.3,那npm会自动下载[email protected]到npx缓存目录运行,所以版本号也要一致。genaiscript.cjs是一个快10万行的打包js文件,好在代码是非压缩的,可以方便地直接修改。我修改的版本是@1.75.3

// genaiscript.cjs
// ../core/src/openai.ts
function getConfigHeaders(cfg) {
  let { token, type, base } = cfg;
	// ... existing code ...
  const fetchHeaders = {
    ...getConfigHeaders(cfg),
    "Content-Type": "application/json",
    ...headers || {}
  };
  traceFetchPost(trace, url, fetchHeaders, postReq);
  const body = JSON.stringify(postReq);
  let r2;
+  // 增加代理抓包,仅针对OpenAI接口的请求
+  const { HttpsProxyAgent } = require('https-proxy-agent');
+  const proxy = 'http://192.168.8.110:9090';
+  const agent = new HttpsProxyAgent(proxy);
  try {
    r2 = await fetchRetry(url, {
+      agent:agent,
      headers: fetchHeaders,
      body,
      method: "POST",
      signal: toSignal(cancellationToken),
      ...rest || {}
    });
// ... existing code ...
+  let toolCall_ids = new Set();
  const doChoices = (json, tokens) => {
    const obj = JSON.parse(json);
    if (!postReq.stream) trace.detailsFenced(`response`, obj, "json");
    if (obj.usage) usage = obj.usage;
    if (!responseModel && obj.model) responseModel = obj.model;
    if (!obj.choices?.length) return;
    else if (obj.choices?.length != 1)
      throw new Error("too many choices in response");
    const choice = obj.choices[0];
    const { finish_reason } = choice;
    if (finish_reason) finishReason = finish_reason;
    if (choice.delta) {
      const { delta, logprobs } = choice;
      if (logprobs?.content) lbs.push(...logprobs.content);
      if (typeof delta?.content === "string" && delta?.content !== "") {
        numTokens += estimateTokens(delta.content, encoder);
        chatResp += delta.content;
        tokens.push(
          ...serializeChunkChoiceToLogProbs(choice)
        );
        trace.appendToken(delta.content);
      } else if (Array.isArray(delta.tool_calls)) {
        const { tool_calls } = delta;
        for (const call of tool_calls) {
+          // 兼容siliconflow, aliyun的qwen72b调用index不正确
+          let id = call.id;
+          if (typeof id == 'string' && id.length > 0 && !toolCall_ids.has(id)) {
+            toolCall_ids.add(id);
+          }
+          let uniq_index = toolCall_ids.size - 1

+          const tc = toolCalls[uniq_index] || (toolCalls[uniq_index] = {
-          const tc = toolCalls[call.index] || (toolCalls[call.index] = {
            id: call.id,
            name: call.function.name,
            arguments: ""
          });
          if (call.function.arguments)
            tc.arguments += call.function.arguments;
          // console.log(JSON.stringify(toolCalls))
        }
      }

标签:...,genaiscript,proxyman,call,delta,obj,const
From: https://www.cnblogs.com/mesopotamiaa/p/18555652

相关文章

  • 【IDER、PyCharm】智能AI编程工具完整教程:ChatGPT Free - Support Key call AI GPT-o1
    文章目录CodeMoss简介CodeMoss的模型集成如何安装和配置CodeMossIDER插件安装步骤CodeMoss的实战使用AI问答功能代码优化与解释优化这段代码解释这段代码文件上传与对话联网查询与GPT助手联网查询GPT助手提升开发效率的最佳实践结语更多文献CodeMoss......
  • java 创建线程的三种方法(Thread,Runnable,Callable)ExecutorService
    1.继承Thread类2.实现Runnable接口3.实现Callable接口4.线程池1.继承Thread类packagecom.chen;//创建线程的方式:继承Thread,重写run(),调用start()开启线程//注意,线程开启不一定立即执行,由cpu调度执行publicclassTestThread2extendsThread{@Overridepublicvoid......
  • bind、call、apply区别?如何实现?
    一、作用:call、apply、bind作用是改变函数执行的上下文,简而言之就是改变函数运行时的this指向二、区别call: 1.传入的参数不固定2.第一个参数是this绑定的对象,后面其余的参数是传入函数执行的参数列表3.第一个参数为null、undefined的......
  • 记一次切面中读取请求体报错 Cannot call getReader()
    问题写了一个切面来处理被指定自定义注解标注的方法:@Slf4j@Aspect@Component@RequiredArgsConstructorpublicclassMyAnnoAspect{privatefinalHttpServletRequestrequest;@Around("@annotation(myAnno)")publicObjecthandleMyAnno(ProceedingJoinPo......
  • useCallback 和 useMemo 使用场景
     一切为了性能,无论是useCallback还是useMemo还是memo,都是为了让不该渲染的组件不去渲染在学习useCallback、useMemo之前,我们需要知道一点,React的渲染是自顶而下,如果父组件渲染了,那么子组件也会渲染,其子孙组件“世世代代”都要渲染但如果父组件的渲染与子组件的pr......
  • Java:An attempt was made to call a method that does not exist. The attempt was ma
    1.问题描述一个字段的类型从int变成了bigint,实体类也要同步更新为Long。修改完后只更新了这个类,结果运行就报错了。根据日志来看说“EntityKsGc.getKscc()Ljava/lang/Long;”这个方法不存在,但就是修改这个类,改成了Long类型,确确实实存在,另外从eclipse来看,也只提示修改了......
  • 织梦自定义图片字段报错 Call to a member function GetInnerText()
    问题:添加自定义图片字段时,前台打开当前栏目列表出现 Fatalerror:CalltoamemberfunctionGetInnerText()onstring 错误。解决方法:修改 customfields.func.php 文件:打开 /include/customfields.func.php 文件,搜索:  $fvalue=trim($ntag->GetInnerTe......
  • 汇编语言-CALL和RET指令
    call和ret都是转移指令,修改Ip或同时修改csip。1.ret和retfret指令用栈中的数据,修改ip的内容。从而实现近转移retf指令用栈中的数据,修改cs和ip的内容,从而实现远转移。CPU执行ret指令时,进行下面两步操作(IP)=((SS)*16+(SP))(SP)=(SP)+2相当于POPIPCPU执行retf指令时进行下......
  • syscall
    syscall分析_syscall_的相关参数:intptr_t_syscall_(intptr_ttype,intptr_ta0,intptr_ta1,intptr_ta2){registerintptr_t_gpr1asm(GPR1)=type;registerintptr_t_gpr2asm(GPR2)=a0;registerintptr_t_gpr3asm(GPR3)=a1;registerintptr_t_......
  • ECE 498/598 Associative Recall Problem
    ECE498/598Fall2024,Homeworks3and4Remarks:HW3&4:Youcanreducethecontextlengthto32ifyouarehavingtroublewiththetrainingtime.HW3&4:Duringtestevaluation,notethatpositionalencodingsforunseen/longcontextarenottrai......