{"id":481535,"date":"2026-05-29T09:19:26","date_gmt":"2026-05-29T09:19:26","guid":{"rendered":"https:\/\/savepearlharbor.com\/?p=481535"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=481535","title":{"rendered":"\u0418\u0418-\u0430\u0433\u0435\u043d\u0442 \u0434\u0432\u043e\u0439\u043d\u043e\u0433\u043e \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f"},"content":{"rendered":"<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0412 \u043d\u0430\u0448\u0438 \u0434\u043d\u0438 \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a, \u043d\u0430\u0432\u0435\u0440\u043d\u044f\u043a\u0430, \u043f\u0440\u043e\u0431\u043e\u0432\u0430\u043b \u0432\u0430\u0439\u0431\u043a\u043e\u0434\u0438\u0442\u044c, \u0430 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0434\u0443\u0442 \u0434\u0430\u043b\u044c\u0448\u0435 \u0438 \u0437\u0430\u0432\u043e\u0434\u044f\u0442 \u0441\u0435\u0431\u0435 \u0446\u0435\u043b\u044b\u0445 \u0418\u0418 \u0430\u0433\u0435\u043d\u0442\u043e\u0432. \u041e\u0434\u043d\u0430\u043a\u043e \u043e\u0442\u043e\u0432\u0441\u044e\u0434\u0443 \u0434\u043e\u043d\u043e\u0441\u044f\u0442\u0441\u044f \u043d\u043e\u0432\u043e\u0441\u0442\u0438 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u043a\u0430\u043a\u043e\u0439-\u0442\u043e AI \u0430\u0433\u0435\u043d\u0442 \u0443\u0434\u0430\u043b\u0438\u043b \u0431\u0430\u0437\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 \u0441\u043e \u0432\u0441\u0435\u043c\u0438 \u0431\u044d\u043a\u0430\u043f\u0430\u043c\u0438. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0445 \u043a\u043e\u0434 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0442\u0430\u043a \u0438\u043b\u0438 \u0438\u043d\u0430\u0447\u0435 \u0441\u0432\u044f\u0437\u0430\u043d\u044b \u0441 \u0430\u0433\u0435\u043d\u0442\u043d\u043e\u0439 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u043e\u0439.<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/c07\/86a\/a20\/c0786aa20fd7c7e8ea171039e30d041b.png\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/c07\/86a\/a20\/c0786aa20fd7c7e8ea171039e30d041b.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/c07\/86a\/a20\/c0786aa20fd7c7e8ea171039e30d041b.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<h3>\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435<\/h3>\n<p>\u0410\u0433\u0435\u043d\u0442\u0441\u043a\u0430\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0438 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 AI-\u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0432\u0441\u0451 \u0442\u0435\u0441\u043d\u0435\u0435 \u0432\u0445\u043e\u0434\u0438\u0442 \u0432 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u043e\u0433\u043e \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0435\u043d\u0438\u044f. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u0440\u0435\u0448\u0438\u043b\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043d\u0430\u0448\u0438\u043c Go \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043a\u0430\u043a-\u0442\u043e \u0441\u0432\u044f\u0437\u0430\u043d\u044b \u0441 \u043d\u0435\u0439\u0440\u043e\u043d\u043d\u044b\u043c\u0438 \u0441\u0435\u0442\u044f\u043c\u0438 \u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u043e\u0439 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e AI. \u042d\u0442\u043e \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u0441\u0435\u0440\u0432\u0435\u0440\u044b \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0445 \u043c\u043e\u0434\u0435\u043b\u0435\u0439, \u0431\u0430\u043b\u0430\u043d\u0441\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0438 \u043d\u0430\u0433\u0440\u0443\u0437\u043e\u043a, \u043f\u0440\u043e\u043a\u0441\u0438-\u0441\u0435\u0440\u0432\u0438\u0441\u044b \u0434\u043b\u044f \u043f\u043e\u0434\u043f\u0438\u0441\u043e\u043a \u0438 \u043c\u043d\u043e\u0433\u043e\u0435 \u0434\u0440\u0443\u0433\u043e\u0435. \u041a \u0442\u043e\u043c\u0443 \u0436\u0435 \u0442\u0430\u043a\u0438\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u044b \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0435 \u0438 \u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0441\u043f\u0440\u043e\u0441\u043e\u043c.<\/p>\n<blockquote>\n<p>\u0415\u0441\u043b\u0438 \u0432\u0430\u043c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0440\u0443\u0447\u043d\u043e \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u0448 Go \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440, \u0442\u043e \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u0440\u0438\u043d\u044f\u0442\u044c \u0443\u0447\u0430\u0441\u0442\u0438\u0435 \u0432 <a href=\"https:\/\/pvs-studio.ru\/ru\/pvs-studio-eap\/\">\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0435 \u0440\u0430\u043d\u043d\u0435\u0433\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u0430<\/a>. EAP \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e \u0434\u043b\u044f \u044f\u0437\u044b\u043a\u043e\u0432 JavaScript, TypeScript \u0438 Go.<\/p>\n<\/blockquote>\n<p>\u041a\u0430\u043a \u0433\u043e\u0432\u043e\u0440\u0438\u0442\u0441\u044f, \u043a\u0443\u0439 \u0436\u0435\u043b\u0435\u0437\u043e, \u043f\u043e\u043a\u0430 \u0433\u043e\u0440\u044f\u0447\u043e, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c \u043a \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432.<\/p>\n<h3>\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432<\/h3>\n<h4>New-api<\/h4>\n<p>\u041d\u0430\u0447\u043d\u0451\u043c \u0441 \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u043e\u0440\u0430 \u0438 \u0431\u0430\u043b\u0430\u043d\u0441\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0434\u043b\u044f \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0430 AI-\u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u043e\u0432 \u2014 <a href=\"https:\/\/github.com\/QuantumNous\/new-api\">new-api<\/a>. \u041e\u043d \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0434\u0435\u0441\u044f\u0442\u043a\u0430\u043c\u0438 API-\u043a\u043b\u044e\u0447\u0435\u0439 \u043e\u0442 \u0440\u0430\u0437\u043d\u044b\u0445 \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u043e\u0432 \u0447\u0435\u0440\u0435\u0437 \u0435\u0434\u0438\u043d\u044b\u0439 \u0448\u043b\u044e\u0437. \u042d\u0442\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043a\u0440\u0443\u043f\u043d\u044b\u0439 \u0438 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 (33 \u0442\u044b\u0441. \u0437\u0432\u0451\u0437\u0434 \u043d\u0430 GitHub), \u043d\u043e \u0434\u0430\u0436\u0435 \u0432 \u0442\u0430\u043a\u0438\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445 \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u044e\u0442\u0441\u044f \u0431\u0430\u0433\u0438 \u0438 \u043f\u043e\u0434\u043e\u0437\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u0434. \u041a\u043e\u043c\u043c\u0438\u0442 <a href=\"https:\/\/github.com\/QuantumNous\/new-api\/tree\/22b6b16702b7a9a5a751d73b2641b334050f2206\"><code>22b6b16<\/code><\/a>.<\/p>\n<pre><code class=\"cpp\">func GetChannel(group string, model string, retry int) (*Channel, error) {  var abilities []Ability  var err error = nil  channelQuery, err := getChannelQuery(group, model, retry)  if err != nil {    return nil, err  }  if common.UsingSQLite || common.UsingPostgreSQL {    err = channelQuery.Order(\"weight DESC\").Find(&amp;abilities).Error  } else {    err = channelQuery.Order(\"weight DESC\").Find(&amp;abilities).Error  }  ....}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:87px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435 PVS-Studio: <a href=\"https:\/\/pvs-studio.ru\/ru\/docs\/warnings\/v8005\/\">V8005<\/a> The \u2018then\u2019 statement is equivalent to the \u2018else\u2019 statement. <a href=\"https:\/\/github.com\/QuantumNous\/new-api\/blob\/5dd0d3bcbd7b1d523bd046a5f9cf9fc8ce28d579\/model\/ability.go#L114\">ability.go 114<\/a><\/p>\n<p>\u0410\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440 \u0441\u043e\u043e\u0431\u0449\u0430\u0435\u0442, \u0447\u0442\u043e <code>if<\/code> \u0441 \u0443\u0441\u043b\u043e\u0432\u0438\u0435\u043c <code>common.UsingSQLite || common.UsingPostgreSQL<\/code> \u043f\u043e \u0441\u0443\u0442\u0438 \u0431\u0435\u0441\u043f\u043e\u043b\u0435\u0437\u0435\u043d, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0432 <code>then<\/code> \u0438 <code>else<\/code> \u0447\u0430\u0441\u0442\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0439 \u043a\u043e\u0434.<\/p>\n<p>\u0410\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u0430\u044f \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0431\u044b\u043b\u0430 \u043d\u0430\u0439\u0434\u0435\u043d\u0430 \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u043e\u0442\u0440\u044b\u0432\u043a\u0435 \u043a\u043e\u0434\u0430:<\/p>\n<pre><code class=\"cpp\">func StreamResponseClaude2OpenAI(....) .... {  ....  if claudeResponse.Type == \"message_start\" {    ....  } else if claudeResponse.Type == \"content_block_start\" {    ....  } else if claudeResponse.Type == \"content_block_delta\" {    ....  } else if claudeResponse.Type == \"message_delta\" {    ....  } else if claudeResponse.Type == \"message_stop\" {    return nil  } else {    return nil  }  ....}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435 PVS-Studio: <a href=\"https:\/\/pvs-studio.ru\/ru\/docs\/warnings\/v8005\/\">V8005<\/a> The \u2018then\u2019 statement is equivalent to the \u2018else\u2019 statement. <a href=\"https:\/\/github.com\/QuantumNous\/new-api\/blob\/5dd0d3bcbd7b1d523bd046a5f9cf9fc8ce28d579\/relay\/channel\/claude\/relay-claude.go#L507\">relay-claude.go 474<\/a><\/p>\n<p>\u0421\u043b\u043e\u0436\u043d\u043e \u043f\u043e\u043d\u044f\u0442\u044c, \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043b\u0438 \u044d\u0442\u043e \u043e\u0448\u0438\u0431\u043a\u0430, \u043b\u0438\u0431\u043e \u0436\u0435 \u0434\u043b\u044f <code>claudeResponse.Type == \"message_stop\"<\/code> \u043f\u043e\u043a\u0430 \u043f\u043e\u043f\u0440\u043e\u0441\u0442\u0443 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043b\u043e\u0433\u0438\u043a\u0430.<\/p>\n<h4>Tau<\/h4>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0441\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u043d\u0438\u0435 \u0432 \u043a\u043e\u0434\u0435 <a href=\"https:\/\/github.com\/taubyte\/tau\">tau<\/a> \u2014 open-source \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0430\u0432\u0442\u043e\u043d\u043e\u043c\u043d\u044b\u0445 \u043e\u0431\u043b\u0430\u0447\u043d\u044b\u0445 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440. \u041a\u043e\u043c\u043c\u0438\u0442 <a href=\"https:\/\/github.com\/taubyte\/tau\/tree\/1e5036ffab19efee73a50c5b0453756995bcb7bf\"><code>1e5036f<\/code><\/a>.<\/p>\n<pre><code class=\"cpp\">func (p *pluginInstance) makeFunc(....) reflect.Value {  ....  _out := make([]reflect.Value, len(cOut))  for idx := 0; idx &lt; len(cOut); idx++ {    switch retTypes[idx] {    case vm.I32Type:      _out[idx] = reflect.ValueOf(int32(cOut[idx]))    case vm.I64Type:                                            \/\/ &lt;=      _out[idx] = reflect.ValueOf(int64(cOut[idx]))    case vm.F32Type:      _out[idx] = reflect.ValueOf(math.Float32frombits(uint32(cOut[idx])))    case vm.I64Type:                                            \/\/ &lt;=      _out[idx] = reflect.ValueOf(math.Float64frombits(cOut[idx]))    }  }  ....}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435 PVS-Studio: V8010 Two or more case branches have equivalent expressions. <a href=\"https:\/\/github.com\/taubyte\/tau\/blob\/c080c757c12b4156cc950c26bca17d40ac950003\/pkg\/vm-orbit\/satellite\/vm\/instance.go#L93\">instance.go 93<\/a><\/p>\n<p>\u0417\u0434\u0435\u0441\u044c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0442\u044c, \u0447\u0442\u043e \u0434\u043b\u044f \u0440\u0430\u0437\u043d\u044b\u0445 <code>case<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043e\u0434\u043d\u043e \u0438 \u0442\u043e \u0436\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 <code>I64Type<\/code>. \u0412 \u0442\u0430\u043a\u043e\u043c \u043a\u043e\u0434\u0435 \u043d\u0435\u0442 \u0441\u043c\u044b\u0441\u043b\u0430, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043a\u043e\u0434 \u0432\u043d\u0443\u0442\u0440\u0438 \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u043a\u0435\u0439\u0441\u0430 \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d. \u0418, \u0441\u043a\u043e\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043e, \u0432\u043c\u0435\u0441\u0442\u043e \u0432\u0442\u043e\u0440\u043e\u0433\u043e <code>I64Type<\/code> \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u043b\u043e\u0441\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>F64Type<\/code>:<\/p>\n<pre><code class=\"cpp\">switch retTypes[idx] {  case vm.I32Type:    _out[idx] = reflect.ValueOf(int32(cOut[idx]))  case vm.I64Type:    _out[idx] = reflect.ValueOf(int64(cOut[idx]))  case vm.F32Type:    _out[idx] = reflect.ValueOf(math.Float32frombits(uint32(cOut[idx])))  case vm.F64Type:     _out[idx] = reflect.ValueOf(math.Float64frombits(cOut[idx])) }<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041a\u0441\u0442\u0430\u0442\u0438, \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0439 \u043f\u0430\u0442\u0442\u0435\u0440\u043d \u043e\u0448\u0438\u0431\u043e\u043a \u0442\u0430\u043a\u0436\u0435 \u0431\u044b\u043b \u043d\u0430\u0439\u0434\u0435\u043d \u0432 \u043a\u043e\u0434\u0435 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u043e\u0433\u043e \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430 \u0440\u0435\u043a\u043b\u0430\u043c\u044b <a href=\"https:\/\/github.com\/AdguardTeam\/AdGuardHome\">AdGuardHome<\/a>. \u041e\u0431 \u044d\u0442\u043e\u043c \u043c\u044b \u043f\u0438\u0441\u0430\u043b\u0438 \u0432 \u0441\u0442\u0430\u0442\u044c\u0435 \u201c<a href=\"https:\/\/pvs-studio.ru\/ru\/blog\/posts\/go\/1342\/#ID5543A82B01\">Go vet \u043d\u0435 \u043f\u043e\u043c\u043e\u0436\u0435\u0442. \u0421\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437 Golang \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e PVS-Studio<\/a>\u201d.<\/p>\n<h4>Sub2api<\/h4>\n<p>\u041f\u0435\u0440\u0435\u0439\u0434\u0451\u043c \u043a \u043f\u0440\u043e\u043a\u0441\u0438-\u0441\u0435\u0440\u0432\u0435\u0440\u0443 \u0434\u043b\u044f AI-\u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u2014 <a href=\"https:\/\/github.com\/Wei-Shaw\/sub2api\">Sub2API<\/a>. \u041a\u043e\u043c\u043c\u0438\u0442 <a href=\"https:\/\/github.com\/Wei-Shaw\/sub2api\/tree\/0f0339301022c18ec7527382d1c7edc7b2933c8f\"><code>0f03393<\/code><\/a>.<\/p>\n<pre><code class=\"cpp\">func cleanJSONSchemaRecursive(value any) any {  ....  if hasKey(schemaMap, \"properties\") {    schemaMap[\"type\"] = \"object\"  } else {  \/\/ \u9ed8\u8ba4\u4e3a string ? or object? Gemini \u901a\u5e38\u9700\u8981\u660e\u786e type    schemaMap[\"type\"] = \"object\"  }  ....}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435 PVS-Studio: <a href=\"https:\/\/pvs-studio.ru\/ru\/docs\/warnings\/v8005\/\">V8005<\/a> The \u2018then\u2019 statement is equivalent to the \u2018else\u2019 statement. <a href=\"https:\/\/github.com\/Wei-Shaw\/sub2api\/blob\/f5bd25bea045e728846b38bf18080ffa48d133c6\/backend\/internal\/pkg\/antigravity\/schema_cleaner.go#L310\">schema_cleaner.go 310<\/a><\/p>\n<p>\u0412 \u044d\u0442\u043e\u043c \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u0435 \u043a\u043e\u0434\u0430 \u0432 <code>then<\/code> \u0438\u043b\u0438 <code>else<\/code> \u0447\u0430\u0441\u0442\u044f\u0445, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0435\u0441\u0442\u044c \u043e\u0448\u0438\u0431\u043a\u0430, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043e\u043d\u0438 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0435. \u0412 \u043b\u0443\u0447\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 <code>if<\/code> \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043b\u0438\u0448\u043d\u0438\u043c \u0438 \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u043a\u043e\u0434 \u0442\u044f\u0436\u0435\u043b\u0435\u0435 \u0447\u0438\u0442\u0430\u0442\u044c.<\/p>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0434\u0440\u0443\u0433\u043e\u0439 \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442:<\/p>\n<pre><code class=\"cpp\">func classifyOpsPhase(errType, message, code string) string {  ....  switch errType {  case \"authentication_error\":    return \"auth\"  case \"billing_error\", \"subscription_error\":    return \"request\"                                  \/\/ &lt;=           case \"rate_limit_error\":    if .... {      return \"request\"    }    return \"upstream\"  case \"invalid_request_error\":    return \"request\"                                  \/\/ &lt;=  case \"upstream_error\", \"overloaded_error\":    return \"upstream\"  case \"api_error\":    if strings.Contains(msg, opsErrNoAvailableAccounts) {      return \"routing\"    }    return \"internal\"  default:    return \"internal\"  }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435 PVS-Studio: <a href=\"https:\/\/pvs-studio.ru\/ru\/docs\/warnings\/v8009\/\">V8009<\/a> Two or more case branches perform the same actions. <a href=\"https:\/\/github.com\/Wei-Shaw\/sub2api\/blob\/f5bd25bea045e728846b38bf18080ffa48d133c6\/backend\/internal\/handler\/ops_error_logger.go#L1125\">ops_error_logger.go 1125<\/a><\/p>\n<p>\u0410\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440 \u043d\u0430\u0448\u0451\u043b \u0432\u0435\u0442\u0432\u0438 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 <code>switch<\/code> \u0441 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u043c \u0442\u0435\u043b\u043e\u043c. \u0421\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u043d\u0438\u044f \u044d\u0442\u043e\u0433\u043e \u0434\u0438\u0430\u0433\u043d\u043e\u0441\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u044e\u0442\u0441\u044f \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0447\u0430\u0441\u0442\u043e, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0434\u043b\u044f \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043a\u0435\u0439\u0441\u043e\u0432 \u043d\u0443\u0436\u043d\u043e \u0438\u043c\u0435\u0442\u044c \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0439 \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u0439 \u043a\u043e\u0434, \u0438 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435 \u043b\u044e\u0431\u044f\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0437\u0430\u043f\u044f\u0442\u0443\u044e \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u0443\u0441\u043b\u043e\u0432\u0438\u0439.<\/p>\n<p>\u0412\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u043f\u0435\u0440\u0432\u044b\u0439 \u043a\u0435\u0439\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>request<\/code>, \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0432 \u0441\u0435\u0431\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 <code>case \"billing_error\", \"subscription_error\"<\/code>. \u0418 \u0432 \u0442\u0430\u043a\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0431\u044b\u043b\u043e \u0431\u044b \u043b\u043e\u0433\u0438\u0447\u043d\u043e \u0447\u0435\u0440\u0435\u0437 \u0437\u0430\u043f\u044f\u0442\u0443\u044e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 <code>case \"invalid_request_error\"<\/code> \u0438\u0437 \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u043a\u0435\u0439\u0441\u0430, \u0435\u0441\u043b\u0438 \u043e\u043d\u0438 \u0432\u0441\u0435\u0433\u0434\u0430 \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442\u044c \u043a \u043e\u0434\u043d\u043e\u043c\u0443 \u0438 \u0442\u043e\u043c\u0443 \u0436\u0435 \u0438\u0441\u0445\u043e\u0434\u0443.<\/p>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e \u0441\u0442\u043e\u0438\u0442 \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u0434\u0440\u0443\u0433\u043e\u0439 \u043a\u0435\u0439\u0441:<\/p>\n<pre><code class=\"cpp\">case \"rate_limit_error\":    if .... {      return \"request\"    }    return \"upstream\"<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041e\u0442\u0441\u044e\u0434\u0430 \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0435\u043d\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>request<\/code>, \u043d\u043e \u0437\u0434\u0435\u0441\u044c \u0435\u0441\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430. \u042d\u0442\u043e \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043d\u0430\u0441 \u043a \u043c\u044b\u0441\u043b\u0438, \u0447\u0442\u043e, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0432\u043e \u0432\u0442\u043e\u0440\u043e\u043c \u043a\u0435\u0439\u0441\u0435 \u0441 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u043c \u0442\u0435\u043b\u043e\u043c \u0442\u0430\u043a\u0436\u0435 \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u043a\u0430\u043a\u0430\u044f-\u0442\u043e \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430. \u041d\u043e \u0438\u0437 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 \u0441\u043b\u043e\u0436\u043d\u043e \u043f\u043e\u043d\u044f\u0442\u044c, \u0447\u0442\u043e \u0438\u043c\u0435\u043d\u043d\u043e \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440 \u043f\u043e\u0434\u0441\u0432\u0435\u0447\u0438\u0432\u0430\u0435\u0442 \u0441\u0442\u0440\u0430\u043d\u043d\u044b\u0439 \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442 \u043a\u043e\u0434\u0430.<\/p>\n<p>\u041f\u043e\u0445\u043e\u0436\u0438\u0439 \u0441\u043b\u0443\u0447\u0430\u0439 \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>classifyopsErrorSource<\/code>:<\/p>\n<pre><code class=\"cpp\">func classifyOpsErrorSource(phase string, message string) string {  \/\/ Standardized sources: client_request|upstream_http|gateway  switch phase {  case \"upstream\":    return \"upstream_http\"  case \"network\":    return \"gateway\"                                  \/\/ &lt;=  case \"request\", \"auth\":    return \"client_request\"  case \"routing\", \"internal\":    return \"gateway\"                                  \/\/ &lt;=  default:    if strings.Contains(strings.ToLower(message), \"upstream\") {      return \"upstream_http\"    }    return \"gateway\"  }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435 PVS-Studio: <a href=\"https:\/\/pvs-studio.ru\/ru\/docs\/warnings\/v8009\/\">V8009<\/a> Two or more case branches perform the same actions. <a href=\"https:\/\/github.com\/Wei-Shaw\/sub2api\/blob\/f5bd25bea045e728846b38bf18080ffa48d133c6\/backend\/internal\/handler\/ops_error_logger.go#L1220\">ops_error_logger.go 1220<\/a><\/p>\n<p>\u0421 \u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u044d\u0442\u043e \u043d\u0435 \u043e\u0448\u0438\u0431\u043a\u0430 \u0438 \u0441\u0442\u043e\u0438\u0442 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0438\u0442\u044c <code>case \"routing\", \"internal\"<\/code> \u0441 <code>case \"network\"<\/code>. \u0410 \u0441 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b, \u0435\u0441\u0442\u044c \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e\u0441\u0442\u044c, \u0447\u0442\u043e \u043d\u0435 \u0445\u0432\u0430\u0442\u0430\u0435\u0442 \u043a\u0430\u043a\u043e\u0433\u043e-\u0442\u043e \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430, \u043a\u0430\u043a \u0432 \u043a\u0435\u0439\u0441\u0435 <code>default<\/code>.<\/p>\n<h4>Photoprism<\/h4>\n<p><a href=\"https:\/\/github.com\/photoprism\/photoprism\">PhotoPristm<\/a> \u2014 self-hosted \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 \u0444\u043e\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u0439 \u0441 \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u043c \u043a\u043e\u0434\u043e\u043c. \u041f\u0440\u043e\u0435\u043a\u0442 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0435\u043d \u0442\u0435\u043c, \u0447\u0442\u043e \u043e\u0431\u043b\u0430\u0434\u0430\u0435\u0442 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u043c AI \u0438 REST API, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0430\u0433\u0435\u043d\u0442\u0443 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0444\u043e\u0442\u043e\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u043e\u0439. \u041a\u043e\u043c\u043c\u0438\u0442 <a href=\"https:\/\/github.com\/photoprism\/photoprism\/tree\/93bb435203a9338da6e781ec8d55e7cdde1aed21\"><code>93bb435<\/code><\/a>.<\/p>\n<pre><code class=\"cpp\">func (c *opticsClusterer) extract() {  ....  switch {  case math.Abs(d) &lt;= c.xi:    cs = areas[j].start    ce = ue  case d &gt; c.xi:    for k := areas[j].end; k &gt; areas[j].end; k-- {                    \/\/ &lt;=      if ....{        cs = k        break      }    }    ce = ue  default:    cs = areas[j].start    for k := i; k &lt; e; k++ {      if ....{        ce = k        break      }    }  }  ....}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435 PVS-Studio: V8016 The loop condition will never be met. Inspect initial and final values in the \u2018for\u2019 loop. <a href=\"https:\/\/github.com\/photoprism\/photoprism\/blob\/464798234a9b7cfeb2ccda22d2f68b8103ea08ec\/pkg\/vector\/alg\/optics.go#L321\">optics.go 321<\/a><\/p>\n<p>\u0410\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440 \u0441\u043e\u043e\u0431\u0449\u0430\u0435\u0442, \u0447\u0442\u043e \u0443\u0441\u043b\u043e\u0432\u0438\u0435 <code>for<\/code> \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u043e, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0438 \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0440\u0430\u0432\u043d\u044b <code>areas[j].end<\/code>. \u0421\u043a\u043e\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043e, \u0437\u0434\u0435\u0441\u044c \u043e\u043f\u0435\u0447\u0430\u0442\u043a\u0430, \u0438 \u0443\u0441\u043b\u043e\u0432\u0438\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"cpp\">for k := areas[j].end; k &gt; areas[j].start; k-- {  ....}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h4>Axonhub<\/h4>\n<p>\u0415\u0449\u0451 \u043e\u0434\u0438\u043d \u043f\u0440\u043e\u043a\u0441\u0438 \u2014 <a href=\"https:\/\/github.com\/looplj\/axonhub\">axonhub<\/a>. \u041a\u043e\u043c\u043c\u0438\u0442 <a href=\"https:\/\/github.com\/looplj\/axonhub\/tree\/bfc11e0114f47726b271c9c800f9bcaa1557bf88\"><code>bfc11e01<\/code><\/a>.<\/p>\n<pre><code class=\"cpp\">func AggregateStreamChunks(....) ([]byte, llm.ResponseMeta, error) {  ....  if event.Delta.Thinking != nil {    if contentBlocks[index].Type == \"thinking\" {      if contentBlocks[index].Thinking == nil {        contentBlocks[index].Thinking = lo.ToPtr(\"\")      }      *contentBlocks[index].Thinking += *event.Delta.Thinking    } else {      \/\/ Convert to thinking block if it's not already      contentBlocks[index].Type = \"thinking\"      contentBlocks[index].Thinking = event.Delta.Thinking    }  }  if event.Delta.Signature != nil {                                      \/\/ &lt;=    \/\/ Handle signature delta - append to thinking block signature    if contentBlocks[index].Type == \"thinking\" {      if event.Delta.Signature != nil {                                  \/\/ &lt;=        if contentBlocks[index].Signature == nil {          contentBlocks[index].Signature = event.Delta.Signature        } else {          contentBlocks[index].Signature = lo.ToPtr(....)        }      }    } else {      \/\/ Convert to thinking block if it's not already      contentBlocks[index].Type = \"thinking\"      contentBlocks[index].Signature = event.Delta.Signature    }  }  ....}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435 PVS-Studio: V8020 Recurring check. The \u2018event.Delta.Signature != nil\u2019 condition was already verified on line 96. <a href=\"https:\/\/github.com\/looplj\/axonhub\/blob\/aab5159add6b8876571e9a222ff25a73f471f7a2\/llm\/transformer\/anthropic\/aggregator.go#L96\">aggregator.go 96<\/a><\/p>\n<p>\u0410\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u043b \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u0443\u044e \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 <code>event.Delta.Signature != nil<\/code>. \u041f\u043e\u0432\u0442\u043e\u0440\u043d\u0430\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0431\u0435\u0441\u0441\u043c\u044b\u0441\u043b\u0435\u043d\u043d\u0430, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043e\u043d\u0430 \u0432\u0441\u0435\u0433\u0434\u0430 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u0442\u0438\u043d\u043d\u043e\u0439.<\/p>\n<h4>LocalAI<\/h4>\n<p>\u041d\u0430 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 <a href=\"https:\/\/github.com\/mudler\/LocalAI\">LocalAI<\/a> \u2014 \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u0439 \u0434\u0432\u0438\u0436\u043e\u043a \u0434\u043b\u044f \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043c\u043e\u0434\u0435\u043b\u0435\u0439 \u0438\u0441\u043a\u0443\u0441\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u043b\u043b\u0435\u043a\u0442\u0430. \u041a\u043e\u043c\u043c\u0438\u0442 <a href=\"https:\/\/github.com\/mudler\/LocalAI\/tree\/dd8e74a486df34cdd2888f1643aecef0099d3a4a\"><code>dd8e74a<\/code><\/a>.<\/p>\n<pre><code class=\"cpp\">func (r *RunCMD) Run(ctx *cliContext.Context) error {  ....  if r.DisableMetricsEndpoint {    opts = append(opts, config.DisableMetricsEndpoint)  }  if r.DisableRuntimeSettings {    opts = append(opts, config.DisableRuntimeSettings)  }  if r.EnableTracing {    opts = append(opts, config.EnableTracing)  }  if r.EnableTracing {    opts = append(opts, config.EnableTracing)  }  opts = append(opts, config.WithTracingMaxItems(r.TracingMaxItems))  ....}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435 PVS-Studio: <a href=\"https:\/\/pvs-studio.ru\/ru\/docs\/warnings\/v8017\/\">V8017<\/a> The conditions of the \u2018if\u2019 statements situated alongside each other are equivalent. Check lines: 158, 162. <a href=\"https:\/\/github.com\/mudler\/LocalAI\/blob\/dd8e74a486df34cdd2888f1643aecef0099d3a4a\/core\/cli\/run.go#L158\">run.go 158<\/a><\/p>\n<p>\u041c\u043e\u0436\u043d\u043e \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>Run<\/code> \u0434\u0443\u0431\u043b\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0441\u0442\u0440\u043e\u0447\u043a\u0438:<\/p>\n<pre><code class=\"cpp\">if r.EnableTracing {    opts = append(opts, config.EnableTracing)  }<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0421 \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e\u0441\u0442\u044c\u044e \u044d\u0442\u043e \u043e\u0448\u0438\u0431\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u043a \u0442\u043e\u043c\u0443, \u0447\u0442\u043e <code>opts = append(opts, config.EnableTracing)<\/code>  \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430 \u0434\u0432\u0430 \u0440\u0430\u0437\u0430, \u0435\u0441\u043b\u0438 <code>r.EnableTracing<\/code> \u0438\u043c\u0435\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>true<\/code>.<\/p>\n<p>\u0422\u0430\u043a\u0436\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0447\u0442\u043e \u0432\u043c\u0435\u0441\u0442\u043e \u0432\u0442\u043e\u0440\u043e\u0433\u043e <code>r.EnableTracing<\/code> \u0438 <code>config.EnableTracing<\/code> \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u0434\u0440\u0443\u0433\u043e\u0435, \u0438 \u0447\u0430\u0441\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430 \u043f\u043e\u043f\u0440\u043e\u0441\u0442\u0443 \u0443\u0442\u0435\u0440\u044f\u043d\u0430. \u0421\u043a\u043e\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043e, \u044d\u0442\u0430 \u043e\u0448\u0438\u0431\u043a\u0430 \u0434\u043e\u043f\u0443\u0449\u0435\u043d\u0430 \u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 copy-paste.<\/p>\n<p>\u041f\u0435\u0440\u0435\u0439\u0434\u0451\u043c \u043a \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c\u0443 \u0441\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u043d\u0438\u044e:<\/p>\n<pre><code class=\"cpp\">func parseXMLWithFormat(s string, format *XMLToolCallFormat) (....) {  ....  for _, match := range toolCallMatches {    if len(match) &lt; 3 {      continue    }    ....    var functionContent string    if len(match) &gt;= 3 {      if format.ToolSep == \"\" &amp;&amp; format.KeyStart != \"\" {        functionContent = match[2]      } else {        functionContent = match[2]      }    }    ....  }  ....}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435 PVS-Studio: <a href=\"https:\/\/pvs-studio.ru\/ru\/docs\/warnings\/v8005\/\">V8005<\/a> The \u2018then\u2019 statement is equivalent to the \u2018else\u2019 statement. <a href=\"https:\/\/github.com\/mudler\/LocalAI\/blob\/dd8e74a486df34cdd2888f1643aecef0099d3a4a\/pkg\/functions\/parse.go#L902\">parse.go 902<\/a><\/p>\n<p>\u041d\u0435\u0432\u043e\u043e\u0440\u0443\u0436\u0451\u043d\u043d\u044b\u043c \u0433\u043b\u0430\u0437\u043e\u043c \u0432\u0438\u0434\u043d\u043e, \u0447\u0442\u043e <code>then<\/code> \u0438 <code>else<\/code> \u0431\u043b\u043e\u043a\u0438 \u0438\u0434\u0435\u043d\u0442\u0438\u0447\u043d\u044b, \u0438 \u0432 \u0442\u0430\u043a\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0435\u0442 \u0441\u043c\u044b\u0441\u043b\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>if<\/code>.<\/p>\n<p>\u0421\u043a\u043e\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043e, \u044d\u0442\u043e \u043e\u0448\u0438\u0431\u043a\u0430 copy-paste, \u0438 \u0432\u043e \u0432\u0442\u043e\u0440\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0435 <code>functionContent = match[2]<\/code> \u0437\u0430\u0431\u044b\u043b\u0438 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0438\u043d\u0434\u0435\u043a\u0441.<\/p>\n<p>\u0418 \u0441\u0440\u0430\u0437\u0443 \u0442\u0440\u0438 \u0441\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u043d\u0438\u044f <a href=\"https:\/\/pvs-studio.ru\/ru\/docs\/warnings\/v8005\/\">V8005<\/a> \u0431\u044b\u043b\u043e \u0432\u044b\u0434\u0430\u043d\u043e \u043d\u0430 \u0442\u0440\u0438 \u043f\u043e\u0445\u043e\u0436\u0438\u0445 \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u0430:<\/p>\n<pre><code class=\"cpp\">func ChatEndpoint(....) echo.HandlerFunc {  ....  if len(cleanedContent) &gt; len(lastEmittedCleanedContent) &amp;&amp;      strings.HasPrefix(cleanedContent, lastEmittedCleanedContent) {    deltaContent = cleanedContent[len(lastEmittedCleanedContent):]    lastEmittedCleanedContent = cleanedContent  } else if cleanedContent != lastEmittedCleanedContent {    \/\/ If cleaned content changed but not in a simple append,     \/\/ extract delta from cleaned content    \/\/ This handles cases where thinking tags are removed mid-stream    if lastEmittedCleanedContent == \"\" {      deltaContent = cleanedContent                             \/\/ &lt;=      lastEmittedCleanedContent = cleanedContent                \/\/ &lt;=    } else {      \/\/ Content changed in non-append way, use the new cleaned content      deltaContent = cleanedContent                             \/\/ &lt;=      lastEmittedCleanedContent = cleanedContent                \/\/ &lt;=    }  }  ....}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435 PVS-Studio: <a href=\"https:\/\/pvs-studio.ru\/ru\/docs\/warnings\/v8005\/\">V8005<\/a> The \u2018then\u2019 statement is equivalent to the \u2018else\u2019 statement. chat.go 85<\/p>\n<p>\u041e\u043f\u044f\u0442\u044c <code>then<\/code> \u0438 <code>else<\/code> \u0438\u043c\u0435\u044e\u0442 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0439 \u043a\u043e\u0434. \u041e\u0434\u043d\u0430\u043a\u043e \u0432 \u044d\u0442\u043e\u0442 \u0440\u0430\u0437 \u0442\u0430\u043a\u0438\u0445 \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u043e\u0432 \u0442\u0440\u0438. \u042d\u0442\u043e \u043d\u0430\u0432\u043e\u0434\u0438\u0442 \u043d\u0430 \u043c\u044b\u0441\u043b\u044c, \u0447\u0442\u043e \u043a\u043e\u0434 \u043c\u043e\u0433 \u0431\u044b\u0442\u044c \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d, \u0430 \u0437\u0430\u0442\u0435\u043c \u0440\u0430\u0441\u0442\u0430\u0441\u043a\u0430\u043d \u043f\u043e \u0434\u0440\u0443\u0433\u0438\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c.<\/p>\n<h3>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h3>\n<p>\u041d\u0430 \u044d\u0442\u043e\u043c \u0432\u0441\u0451. \u0415\u0441\u043b\u0438 \u0432\u0430\u043c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b \u0440\u0430\u0437\u0431\u043e\u0440\u044b \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432, \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f AI \u0438 \u0430\u0433\u0435\u043d\u0442\u043d\u043e\u0439 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438, \u0442\u043e \u043c\u043e\u0436\u0435\u0442\u0435 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043e\u0431 \u044d\u0442\u043e\u043c \u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f\u0445, \u0438 \u043c\u044b \u0443\u0447\u0442\u0451\u043c \u0432\u0430\u0448\u0435 \u043c\u043d\u0435\u043d\u0438\u0435 \ud83d\ude42<\/p>\n<blockquote>\n<p>\u041d\u0430\u043f\u043e\u043c\u043d\u044e, \u0447\u0442\u043e \u043d\u0435\u0434\u0430\u0432\u043d\u043e \u0432 PVS-Studio \u043f\u043e\u044f\u0432\u0438\u043b\u0430\u0441\u044c <a href=\"https:\/\/pvs-studio.ru\/ru\/pvs-studio-eap\/\">\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u0440\u0430\u043d\u043d\u0435\u0433\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u0430<\/a> \u043a \u043d\u0430\u0448\u0438\u043c \u043d\u043e\u0432\u044b\u043c \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u0430\u043c, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u0440\u0438\u043d\u044f\u0442\u044c \u0443\u0447\u0430\u0441\u0442\u0438\u0435! EAP \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e \u0434\u043b\u044f \u044f\u0437\u044b\u043a\u043e\u0432 JavaScript, TypeScript \u0438 Go.<\/p>\n<\/blockquote>\n<p>\u0415\u0441\u043b\u0438 \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e PVS-Studio, \u0442\u043e \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440 \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e <a href=\"https:\/\/pvs-studio.ru\/ru\/pvs-studio\/try-free\/?utm_source=website&amp;utm_medium=habr&amp;utm_campaign=article&amp;utm_content=1377\">\u0441\u0441\u044b\u043b\u043a\u0435<\/a>!<\/p>\n<p>\u0411\u0435\u0440\u0435\u0433\u0438\u0442\u0435 \u0441\u0435\u0431\u044f \u0438 \u0441\u0432\u043e\u0439 \u043a\u043e\u0434!<\/p>\n<p>\u0415\u0441\u043b\u0438 \u0445\u043e\u0442\u0438\u0442\u0435 \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435\u0439 \u0441 \u0430\u043d\u0433\u043b\u043e\u044f\u0437\u044b\u0447\u043d\u043e\u0439 \u0430\u0443\u0434\u0438\u0442\u043e\u0440\u0438\u0435\u0439, \u0442\u043e \u043f\u0440\u043e\u0448\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u043f\u0435\u0440\u0435\u0432\u043e\u0434: Georgii Tormozov. <a href=\"https:\/\/pvs-studio.com\/en\/blog\/posts\/1377\/\">Double AI agents: What\u2019s hiding in your Golang code<\/a>.<\/p>\n<\/div>\n<p>\u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/1041056\/\">https:\/\/habr.com\/ru\/articles\/1041056\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u0412 \u043d\u0430\u0448\u0438 \u0434\u043d\u0438 \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a, \u043d\u0430\u0432\u0435\u0440\u043d\u044f\u043a\u0430, \u043f\u0440\u043e\u0431\u043e\u0432\u0430\u043b \u0432\u0430\u0439\u0431\u043a\u043e\u0434\u0438\u0442\u044c, \u0430 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0434\u0443\u0442 \u0434\u0430\u043b\u044c\u0448\u0435 \u0438 \u0437\u0430\u0432\u043e\u0434\u044f\u0442 \u0441\u0435\u0431\u0435 \u0446\u0435\u043b\u044b\u0445 \u0418\u0418 \u0430\u0433\u0435\u043d\u0442\u043e\u0432. \u041e\u0434\u043d\u0430\u043a\u043e \u043e\u0442\u043e\u0432\u0441\u044e\u0434\u0443 \u0434\u043e\u043d\u043e\u0441\u044f\u0442\u0441\u044f \u043d\u043e\u0432\u043e\u0441\u0442\u0438 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u043a\u0430\u043a\u043e\u0439-\u0442\u043e AI \u0430\u0433\u0435\u043d\u0442 \u0443\u0434\u0430\u043b\u0438\u043b \u0431\u0430\u0437\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 \u0441\u043e \u0432\u0441\u0435\u043c\u0438 \u0431\u044d\u043a\u0430\u043f\u0430\u043c\u0438. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0445 \u043a\u043e\u0434 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0442\u0430\u043a \u0438\u043b\u0438 \u0438\u043d\u0430\u0447\u0435 \u0441\u0432\u044f\u0437\u0430\u043d\u044b \u0441 \u0430\u0433\u0435\u043d\u0442\u043d\u043e\u0439 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u043e\u0439.\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435\u0410\u0433\u0435\u043d\u0442\u0441\u043a\u0430\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0438 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 AI-\u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0432\u0441\u0451 \u0442\u0435\u0441\u043d\u0435\u0435 \u0432\u0445\u043e\u0434\u0438\u0442 \u0432 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u043e\u0433\u043e \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0435\u043d\u0438\u044f. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u0440\u0435\u0448\u0438\u043b\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043d\u0430\u0448\u0438\u043c Go \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043a\u0430\u043a-\u0442\u043e \u0441\u0432\u044f\u0437\u0430\u043d\u044b \u0441 \u043d\u0435\u0439\u0440\u043e\u043d\u043d\u044b\u043c\u0438 \u0441\u0435\u0442\u044f\u043c\u0438 \u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u043e\u0439 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e AI. \u042d\u0442\u043e \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u0441\u0435\u0440\u0432\u0435\u0440\u044b \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0445 \u043c\u043e\u0434\u0435\u043b\u0435\u0439, \u0431\u0430\u043b\u0430\u043d\u0441\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0438 \u043d\u0430\u0433\u0440\u0443\u0437\u043e\u043a, \u043f\u0440\u043e\u043a\u0441\u0438-\u0441\u0435\u0440\u0432\u0438\u0441\u044b \u0434\u043b\u044f \u043f\u043e\u0434\u043f\u0438\u0441\u043e\u043a \u0438 \u043c\u043d\u043e\u0433\u043e\u0435 \u0434\u0440\u0443\u0433\u043e\u0435. \u041a \u0442\u043e\u043c\u0443 \u0436\u0435 \u0442\u0430\u043a\u0438\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u044b \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0435 \u0438 \u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0441\u043f\u0440\u043e\u0441\u043e\u043c.\u0415\u0441\u043b\u0438 \u0432\u0430\u043c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0440\u0443\u0447\u043d\u043e \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u0448 Go \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440, \u0442\u043e \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u0440\u0438\u043d\u044f\u0442\u044c \u0443\u0447\u0430\u0441\u0442\u0438\u0435 \u0432 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0435 \u0440\u0430\u043d\u043d\u0435\u0433\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u0430. EAP \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e \u0434\u043b\u044f \u044f\u0437\u044b\u043a\u043e\u0432 JavaScript, TypeScript \u0438 Go.\u041a\u0430\u043a \u0433\u043e\u0432\u043e\u0440\u0438\u0442\u0441\u044f, \u043a\u0443\u0439 \u0436\u0435\u043b\u0435\u0437\u043e, \u043f\u043e\u043a\u0430 \u0433\u043e\u0440\u044f\u0447\u043e, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c \u043a \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432.\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432New-api\u041d\u0430\u0447\u043d\u0451\u043c \u0441 \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u043e\u0440\u0430 \u0438 \u0431\u0430\u043b\u0430\u043d\u0441\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0434\u043b\u044f \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0430 AI-\u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u043e\u0432 \u2014 new-api. \u041e\u043d \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0434\u0435\u0441\u044f\u0442\u043a\u0430\u043c\u0438 API-\u043a\u043b\u044e\u0447\u0435\u0439 \u043e\u0442 \u0440\u0430\u0437\u043d\u044b\u0445 \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u043e\u0432 \u0447\u0435\u0440\u0435\u0437 \u0435\u0434\u0438\u043d\u044b\u0439 \u0448\u043b\u044e\u0437. \u042d\u0442\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043a\u0440\u0443\u043f\u043d\u044b\u0439 \u0438 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 (33 \u0442\u044b\u0441. \u0437\u0432\u0451\u0437\u0434 \u043d\u0430 GitHub), \u043d\u043e \u0434\u0430\u0436\u0435 \u0432 \u0442\u0430\u043a\u0438\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445 \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u044e\u0442\u0441\u044f \u0431\u0430\u0433\u0438 \u0438 \u043f\u043e\u0434\u043e\u0437\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u0434. \u041a\u043e\u043c\u043c\u0438\u0442 22b6b16.func GetChannel(group string, model string, retry int) (*Channel, error) {  var abilities []Ability  var err error = nil  channelQuery, err := getChannelQuery(group, model, retry)  if err != nil {    return nil, err  }  if common.UsingSQLite || common.UsingPostgreSQL {    err = channelQuery.Order(&#171;weight DESC&#187;).Find(&amp;abilities).Error  } else {    err = channelQuery.Order(&#171;weight DESC&#187;).Find(&amp;abilities).Error  }  &#8230;.}\u041f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435 PVS-Studio: V8005 The \u2018then\u2019 statement is equivalent to the \u2018else\u2019 statement. ability.go 114\u0410\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440 \u0441\u043e\u043e\u0431\u0449\u0430\u0435\u0442, \u0447\u0442\u043e if \u0441 \u0443\u0441\u043b\u043e\u0432\u0438\u0435\u043c common.UsingSQLite || common.UsingPostgreSQL \u043f\u043e \u0441\u0443\u0442\u0438 \u0431\u0435\u0441\u043f\u043e\u043b\u0435\u0437\u0435\u043d, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0432 then \u0438 else \u0447\u0430\u0441\u0442\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0439 \u043a\u043e\u0434.\u0410\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u0430\u044f \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0431\u044b\u043b\u0430 \u043d\u0430\u0439\u0434\u0435\u043d\u0430 \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u043e\u0442\u0440\u044b\u0432\u043a\u0435 \u043a\u043e\u0434\u0430:func StreamResponseClaude2OpenAI(&#8230;.) &#8230;. {  &#8230;.  if claudeResponse.Type == &#171;message_start&#187; {    &#8230;.  } else if claudeResponse.Type == &#171;content_block_start&#187; {    &#8230;.  } else if claudeResponse.Type == &#171;content_block_delta&#187; {    &#8230;.  } else if claudeResponse.Type == &#171;message_delta&#187; {    &#8230;.  } else if claudeResponse.Type == &#171;message_stop&#187; {    return nil  } else {    return nil  }  &#8230;.}\u041f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435 PVS-Studio: V8005 The \u2018then\u2019 statement is equivalent to the \u2018else\u2019 statement. relay-claude.go 474\u0421\u043b\u043e\u0436\u043d\u043e \u043f\u043e\u043d\u044f\u0442\u044c, \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043b\u0438 \u044d\u0442\u043e \u043e\u0448\u0438\u0431\u043a\u0430, \u043b\u0438\u0431\u043e \u0436\u0435 \u0434\u043b\u044f claudeResponse.Type == &#171;message_stop&#187; \u043f\u043e\u043a\u0430 \u043f\u043e\u043f\u0440\u043e\u0441\u0442\u0443 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043b\u043e\u0433\u0438\u043a\u0430.Tau\u0422\u0435\u043f\u0435\u0440\u044c \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0441\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u043d\u0438\u0435 \u0432 \u043a\u043e\u0434\u0435 tau \u2014 open-source \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0430\u0432\u0442\u043e\u043d\u043e\u043c\u043d\u044b\u0445 \u043e\u0431\u043b\u0430\u0447\u043d\u044b\u0445 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440. \u041a\u043e\u043c\u043c\u0438\u0442 1e5036f.func (p *pluginInstance) makeFunc(&#8230;.) reflect.Value {  &#8230;.  _out := make([]reflect.Value, len(cOut))  for idx := 0; idx &lt; len(cOut); idx++ {    switch retTypes[idx] {    case vm.I32Type:      _out[idx] = reflect.ValueOf(int32(cOut[idx]))    case vm.I64Type:                                            \/\/ &lt;=      _out[idx] = reflect.ValueOf(int64(cOut[idx]))    case vm.F32Type:      _out[idx] = reflect.ValueOf(math.Float32frombits(uint32(cOut[idx])))    case vm.I64Type:                                            \/\/ &lt;=      _out[idx] = reflect.ValueOf(math.Float64frombits(cOut[idx]))    }  }  &#8230;.}\u041f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435 PVS-Studio: V8010 Two or more case branches have equivalent expressions. instance.go 93\u0417\u0434\u0435\u0441\u044c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0442\u044c, \u0447\u0442\u043e \u0434\u043b\u044f \u0440\u0430\u0437\u043d\u044b\u0445 case \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043e\u0434\u043d\u043e \u0438 \u0442\u043e \u0436\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 I64Type. \u0412 \u0442\u0430\u043a\u043e\u043c \u043a\u043e\u0434\u0435 \u043d\u0435\u0442 \u0441\u043c\u044b\u0441\u043b\u0430, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043a\u043e\u0434 \u0432\u043d\u0443\u0442\u0440\u0438 \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u043a\u0435\u0439\u0441\u0430 \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d. \u0418, \u0441\u043a\u043e\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043e, \u0432\u043c\u0435\u0441\u0442\u043e \u0432\u0442\u043e\u0440\u043e\u0433\u043e I64Type \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u043b\u043e\u0441\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c F64Type:switch retTypes[idx] {  case vm.I32Type:    _out[idx] = reflect.ValueOf(int32(cOut[idx]))  case vm.I64Type:    _out[idx] = reflect.ValueOf(int64(cOut[idx]))  case vm.F32Type:    _out[idx] = reflect.ValueOf(math.Float32frombits(uint32(cOut[idx])))  case vm.F64Type:     _out[idx] = reflect.ValueOf(math.Float64frombits(cOut[idx])) }\u041a\u0441\u0442\u0430\u0442\u0438, \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0439 \u043f\u0430\u0442\u0442\u0435\u0440\u043d \u043e\u0448\u0438\u0431\u043e\u043a \u0442\u0430\u043a\u0436\u0435 \u0431\u044b\u043b \u043d\u0430\u0439\u0434\u0435\u043d \u0432 \u043a\u043e\u0434\u0435 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u043e\u0433\u043e \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430 \u0440\u0435\u043a\u043b\u0430\u043c\u044b AdGuardHome. \u041e\u0431 \u044d\u0442\u043e\u043c \u043c\u044b \u043f\u0438\u0441\u0430\u043b\u0438 \u0432 \u0441\u0442\u0430\u0442\u044c\u0435 \u201cGo vet \u043d\u0435 \u043f\u043e\u043c\u043e\u0436\u0435\u0442. \u0421\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437 Golang \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e PVS-Studio\u201d.Sub2api\u041f\u0435\u0440\u0435\u0439\u0434\u0451\u043c \u043a \u043f\u0440\u043e\u043a\u0441\u0438-\u0441\u0435\u0440\u0432\u0435\u0440\u0443 \u0434\u043b\u044f AI-\u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u2014 Sub2API. \u041a\u043e\u043c\u043c\u0438\u0442 0f03393.func cleanJSONSchemaRecursive(value any) any {  &#8230;.  if hasKey(schemaMap, &#171;properties&#187;) {    schemaMap[&#171;type&#187;] = &#171;object&#187;  } else {  \/\/ \u9ed8\u8ba4\u4e3a string ? or object? Gemini \u901a\u5e38\u9700\u8981\u660e\u786e type    schemaMap[&#171;type&#187;] = &#171;object&#187;  }  &#8230;.}\u041f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435 PVS-Studio: V8005 The \u2018then\u2019 statement is equivalent to the \u2018else\u2019 statement. schema_cleaner.go 310\u0412 \u044d\u0442\u043e\u043c \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u0435 \u043a\u043e\u0434\u0430 \u0432 then \u0438\u043b\u0438 else \u0447\u0430\u0441\u0442\u044f\u0445, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0435\u0441\u0442\u044c \u043e\u0448\u0438\u0431\u043a\u0430, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043e\u043d\u0438 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0435. \u0412 \u043b\u0443\u0447\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 if \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043b\u0438\u0448\u043d\u0438\u043c \u0438 \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u043a\u043e\u0434 \u0442\u044f\u0436\u0435\u043b\u0435\u0435 \u0447\u0438\u0442\u0430\u0442\u044c.\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0434\u0440\u0443\u0433\u043e\u0439 \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442:func classifyOpsPhase(errType, message, code string) string {  &#8230;.  switch errType {  case &#171;authentication_error&#187;:    return &#171;auth&#187;  case &#171;billing_error&#187;, &#171;subscription_error&#187;:    return &#171;request&#187;                                  \/\/ &lt;=           case &#171;rate_limit_error&#187;:    if &#8230;. {      return &#171;request&#187;    }    return &#171;upstream&#187;  case &#171;invalid_request_error&#187;:    return &#171;request&#187;                                  \/\/ &lt;=  case &#171;upstream_error&#187;, &#171;overloaded_error&#187;:    return &#171;upstream&#187;  case &#171;api_error&#187;:    if strings.Contains(msg, opsErrNoAvailableAccounts) {      return &#171;routing&#187;    }    return &#171;internal&#187;  default:    return &#171;internal&#187;  }}\u041f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435 PVS-Studio: V8009 Two or more case branches perform the same actions. ops_error_logger.go 1125\u0410\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440 \u043d\u0430\u0448\u0451\u043b \u0432\u0435\u0442\u0432\u0438 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 switch \u0441 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u043c \u0442\u0435\u043b\u043e\u043c. \u0421\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u043d\u0438\u044f \u044d\u0442\u043e\u0433\u043e \u0434\u0438\u0430\u0433\u043d\u043e\u0441\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u044e\u0442\u0441\u044f \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0447\u0430\u0441\u0442\u043e, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0434\u043b\u044f \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043a\u0435\u0439\u0441\u043e\u0432 \u043d\u0443\u0436\u043d\u043e \u0438\u043c\u0435\u0442\u044c \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0439 \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u0439 \u043a\u043e\u0434, \u0438 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435 \u043b\u044e\u0431\u044f\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0437\u0430\u043f\u044f\u0442\u0443\u044e \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u0443\u0441\u043b\u043e\u0432\u0438\u0439.\u0412\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u043f\u0435\u0440\u0432\u044b\u0439 \u043a\u0435\u0439\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 request, \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0432 \u0441\u0435\u0431\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 case &#171;billing_error&#187;, &#171;subscription_error&#187;. \u0418 \u0432 \u0442\u0430\u043a\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0431\u044b\u043b\u043e \u0431\u044b \u043b\u043e\u0433\u0438\u0447\u043d\u043e \u0447\u0435\u0440\u0435\u0437 \u0437\u0430\u043f\u044f\u0442\u0443\u044e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 case &#171;invalid_request_error&#187; \u0438\u0437 \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u043a\u0435\u0439\u0441\u0430, \u0435\u0441\u043b\u0438 \u043e\u043d\u0438 \u0432\u0441\u0435\u0433\u0434\u0430 \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442\u044c \u043a \u043e\u0434\u043d\u043e\u043c\u0443 \u0438 \u0442\u043e\u043c\u0443 \u0436\u0435 \u0438\u0441\u0445\u043e\u0434\u0443.\u041e\u0434\u043d\u0430\u043a\u043e \u0441\u0442\u043e\u0438\u0442 \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u0434\u0440\u0443\u0433\u043e\u0439 \u043a\u0435\u0439\u0441:case &#171;rate_limit_error&#187;:    if &#8230;. {      return &#171;request&#187;    }    return &#171;upstream&#187;\u041e\u0442\u0441\u044e\u0434\u0430 \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0435\u043d\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 request, \u043d\u043e \u0437\u0434\u0435\u0441\u044c \u0435\u0441\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430. \u042d\u0442\u043e \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043d\u0430\u0441 \u043a \u043c\u044b\u0441\u043b\u0438, \u0447\u0442\u043e, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0432\u043e \u0432\u0442\u043e\u0440\u043e\u043c \u043a\u0435\u0439\u0441\u0435 \u0441 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u043c \u0442\u0435\u043b\u043e\u043c \u0442\u0430\u043a\u0436\u0435 \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u043a\u0430\u043a\u0430\u044f-\u0442\u043e \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430. \u041d\u043e \u0438\u0437 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 \u0441\u043b\u043e\u0436\u043d\u043e \u043f\u043e\u043d\u044f\u0442\u044c, \u0447\u0442\u043e \u0438\u043c\u0435\u043d\u043d\u043e \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440 \u043f\u043e\u0434\u0441\u0432\u0435\u0447\u0438\u0432\u0430\u0435\u0442 \u0441\u0442\u0440\u0430\u043d\u043d\u044b\u0439 \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442 \u043a\u043e\u0434\u0430.\u041f\u043e\u0445\u043e\u0436\u0438\u0439 \u0441\u043b\u0443\u0447\u0430\u0439 \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 classifyopsErrorSource:func classifyOpsErrorSource(phase string, message string) string {  \/\/ Standardized sources: client_request|upstream_http|gateway  switch phase {  case &#171;upstream&#187;:    return &#171;upstream_http&#187;  case &#171;network&#187;:    return &#171;gateway&#187;                                  \/\/ &lt;=  case &#171;request&#187;, &#171;auth&#187;:    return &#171;client_request&#187;  case &#171;routing&#187;, &#171;internal&#187;:    return &#171;gateway&#187;                                  \/\/ &lt;=  default:    if strings.Contains(strings.ToLower(message), &#171;upstream&#187;) {      return &#171;upstream_http&#187;    }    return &#171;gateway&#187;  }}\u041f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435 PVS-Studio: V8009 Two or more case branches perform the same actions. ops_error_logger.go 1220\u0421 \u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u044d\u0442\u043e \u043d\u0435 \u043e\u0448\u0438\u0431\u043a\u0430 \u0438 \u0441\u0442\u043e\u0438\u0442 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0438\u0442\u044c case &#171;routing&#187;, &#171;internal&#187; \u0441 case &#171;network&#187;. \u0410 \u0441 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b, \u0435\u0441\u0442\u044c \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e\u0441\u0442\u044c, \u0447\u0442\u043e \u043d\u0435 \u0445\u0432\u0430\u0442\u0430\u0435\u0442 \u043a\u0430\u043a\u043e\u0433\u043e-\u0442\u043e \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430, \u043a\u0430\u043a \u0432 \u043a\u0435\u0439\u0441\u0435 default.PhotoprismPhotoPristm \u2014 self-hosted \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 \u0444\u043e\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u0439 \u0441 \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u043c \u043a\u043e\u0434\u043e\u043c. \u041f\u0440\u043e\u0435\u043a\u0442 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0435\u043d \u0442\u0435\u043c, \u0447\u0442\u043e \u043e\u0431\u043b\u0430\u0434\u0430\u0435\u0442 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u043c AI \u0438 REST API, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0430\u0433\u0435\u043d\u0442\u0443 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0444\u043e\u0442\u043e\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u043e\u0439. \u041a\u043e\u043c\u043c\u0438\u0442 93bb435.func (c *opticsClusterer) extract() {  &#8230;.  switch {  case math.Abs(d) &lt;= c.xi:    cs = areas[j].start    ce = ue  case d &gt; c.xi:    for k := areas[j].end; k &gt; areas[j].end; k&#8212; {                    \/\/ &lt;=      if &#8230;.{        cs = k        break      }    }    ce = ue  default:    cs = areas[j].start    for k := i; k &lt; e; k++ {      if &#8230;.{        ce = k        break      }    }  }  &#8230;.}\u041f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435 PVS-Studio: V8016 The loop condition will never be met. Inspect initial and final values in the \u2018for\u2019 loop. optics.go 321\u0410\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440 \u0441\u043e\u043e\u0431\u0449\u0430\u0435\u0442, \u0447\u0442\u043e \u0443\u0441\u043b\u043e\u0432\u0438\u0435 for \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u043e, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0438 \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0440\u0430\u0432\u043d\u044b areas[j].end. \u0421\u043a\u043e\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043e, \u0437\u0434\u0435\u0441\u044c \u043e\u043f\u0435\u0447\u0430\u0442\u043a\u0430, \u0438 \u0443\u0441\u043b\u043e\u0432\u0438\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:for k := areas[j].end; k &gt; areas[j].start; k&#8212; {  &#8230;.}Axonhub\u0415\u0449\u0451 \u043e\u0434\u0438\u043d \u043f\u0440\u043e\u043a\u0441\u0438 \u2014 axonhub. \u041a\u043e\u043c\u043c\u0438\u0442 bfc11e01.func AggregateStreamChunks(&#8230;.) ([]byte, llm.ResponseMeta, error) {  &#8230;.  if event.Delta.Thinking != nil {    if contentBlocks[index].Type == &#171;thinking&#187; {      if contentBlocks[index].Thinking == nil {        contentBlocks[index].Thinking = lo.ToPtr(&#171;&#187;)      }      *contentBlocks[index].Thinking += *event.Delta.Thinking    } else {      \/\/ Convert to thinking block if it&#8217;s not already      contentBlocks[index].Type = &#171;thinking&#187;      contentBlocks[index].Thinking = event.Delta.Thinking    }  }  if event.Delta.Signature != nil {                                      \/\/ &lt;=    \/\/ Handle signature delta &#8212; append to thinking block signature    if contentBlocks[index].Type == &#171;thinking&#187; {      if event.Delta.Signature != nil {                                  \/\/ &lt;=        if contentBlocks[index].Signature == nil {          contentBlocks[index].Signature = event.Delta.Signature        } else {          contentBlocks[index].Signature = lo.ToPtr(&#8230;.)        }      }    } else {      \/\/ Convert to thinking block if it&#8217;s not already      contentBlocks[index].Type = &#171;thinking&#187;      contentBlocks[index].Signature = event.Delta.Signature    }  }  &#8230;.}\u041f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435 PVS-Studio: V8020 Recurring check. The&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-481535","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/481535","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=481535"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/481535\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=481535"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=481535"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=481535"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}