@gitkraken/ai-provider-tools 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +3 -3
- package/dist/providers/gitkraken.js +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## 0.3.0
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
### Minor Changes
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
- [#247](https://github.com/gitkraken/core-tools/pull/247) [`998e498`](https://github.com/gitkraken/core-tools/commit/998e4981ec70457e60444f180668ccbd578022ee) Thanks [@JBUinfo](https://github.com/JBUinfo)! - The hosted task `ai.generate` telemetry event now carries `action` (the task action) and `duration_ms` (the task HTTP call duration); chat and BYOK events are unchanged.
|
|
8
8
|
|
|
9
9
|
## [0.2.0] - 2026-10-26
|
|
10
10
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{AiError as e,isAbortError as t,toAiError as n,wireErrorFields as r}from"../errors.js";import{classifyGitKrakenHttpError as i}from"./gitkraken-errors.js";import{toWireMessages as a,toWireTools as o,wireContent as s}from"./gitkraken-wire.js";import{normalizeFinishReason as c,parseOpenAICompatibleStream as l}from"./gitkraken-stream.js";import{defaultRequest as u}from"@gitkraken/api-tools";const d=`message-prompt`;function f(e,t=``){let n=e.baseUrl??`https://api.gitkraken.dev/`,r=n.endsWith(`/`)?n:`${n}/`;return new URL(`v1/ai-tasks${t}`,r).toString()}async function p(n){if(!n.getToken)throw new e(`not_logged_in`,"the gitkraken provider requires `getToken` to be configured");try{return await n.getToken()}catch(n){throw t(n)?n:new e(`not_logged_in`,`failed to obtain a GitKraken token`,{cause:n})}}async function m(e,t){let n={Authorization:`Bearer ${await p(e)}`};return e.organizationId&&(n[`GK-Org-Id`]=e.organizationId),t&&(n[`GK-Action`]=t),e.client&&(n[`Client-Name`]=e.client.name,n[`Client-Version`]=e.client.version),n}function h(e){return typeof e==`string`?e:e==null?``:JSON.stringify(e)}function g(t){if(typeof t==`string`){if(t.length===0)return{};try{return JSON.parse(t)}catch(t){throw new e(`provider_error`,`AI service returned a malformed response`,{cause:t})}}return t??{}}function _(e,t){!t||!e.onCreditUsage||t.limit==null||t.limit<=0||t.used==null||e.onCreditUsage({used:t.used,limit:t.limit,resetsOn:t.resetsOn&&!Number.isNaN(Date.parse(t.resetsOn))?new Date(t.resetsOn).toISOString():t.resetsOn,organizationId:e.organizationId})}async function v(e,t){try{let n=a(t.messages);t.system&&n.unshift({role:`system`,content:s(t.system,!1)});let r={model:t.model||void 0,messages:n,max_tokens:t.maxTokens||void 0,stream:!0,stream_options:{include_usage:!0},temperature:t.temperature??0,tools:o(t.tools)},u=await m(e,t.action||`compose-changes`);u[`Content-Type`]=`application/json`,u.Accept=`text/event-stream`,t.conversationId&&(u[`GK-Conversation-ID`]=t.conversationId);let d=await(e.fetch??globalThis.fetch)(f(e,`/chat/completions`),{method:`POST`,redirect:`manual`,headers:u,body:JSON.stringify(r),signal:t.signal}),p=await d.text();if(!d.ok)throw await i(d.status,p,e);let h=l(p);return _(e,h.gk),e.telemetry?.event(`ai.generate`,{provider:`gitkraken`,kind:`chat`}),{text:h.content,toolCalls:h.toolCalls.length>0?h.toolCalls:void 0,usage:h.promptTokens||h.completionTokens||h.totalTokens?{inputTokens:h.promptTokens,outputTokens:h.completionTokens}:void 0,finishReason:c(h.finishReason),rawFinishReason:h.finishReason,...h.model?{model:h.model}:{}}}catch(t){throw e.telemetry?.exception(t,{provider:`gitkraken`,kind:`chat`}),n(t,`AI request failed`)}}function y(e){return{async generate(t){let n=t.messages,r=`tools`in t?t.tools:void 0;return v(e,{model:e.model,conversationId:e.conversationId,system:t.system,messages:n,tools:r,maxTokens:t.maxTokens,temperature:t.temperature,signal:t.signal})}}}async function b(t,a){try{let n=t.request??u,o={taskType:d,action:a.action,messages:[{content:a.prompt}],model:(a.model??t.model)||void 0},s=
|
|
1
|
+
import{AiError as e,isAbortError as t,toAiError as n,wireErrorFields as r}from"../errors.js";import{classifyGitKrakenHttpError as i}from"./gitkraken-errors.js";import{toWireMessages as a,toWireTools as o,wireContent as s}from"./gitkraken-wire.js";import{normalizeFinishReason as c,parseOpenAICompatibleStream as l}from"./gitkraken-stream.js";import{defaultRequest as u}from"@gitkraken/api-tools";const d=`message-prompt`;function f(e,t=``){let n=e.baseUrl??`https://api.gitkraken.dev/`,r=n.endsWith(`/`)?n:`${n}/`;return new URL(`v1/ai-tasks${t}`,r).toString()}async function p(n){if(!n.getToken)throw new e(`not_logged_in`,"the gitkraken provider requires `getToken` to be configured");try{return await n.getToken()}catch(n){throw t(n)?n:new e(`not_logged_in`,`failed to obtain a GitKraken token`,{cause:n})}}async function m(e,t){let n={Authorization:`Bearer ${await p(e)}`};return e.organizationId&&(n[`GK-Org-Id`]=e.organizationId),t&&(n[`GK-Action`]=t),e.client&&(n[`Client-Name`]=e.client.name,n[`Client-Version`]=e.client.version),n}function h(e){return typeof e==`string`?e:e==null?``:JSON.stringify(e)}function g(t){if(typeof t==`string`){if(t.length===0)return{};try{return JSON.parse(t)}catch(t){throw new e(`provider_error`,`AI service returned a malformed response`,{cause:t})}}return t??{}}function _(e,t){!t||!e.onCreditUsage||t.limit==null||t.limit<=0||t.used==null||e.onCreditUsage({used:t.used,limit:t.limit,resetsOn:t.resetsOn&&!Number.isNaN(Date.parse(t.resetsOn))?new Date(t.resetsOn).toISOString():t.resetsOn,organizationId:e.organizationId})}async function v(e,t){try{let n=a(t.messages);t.system&&n.unshift({role:`system`,content:s(t.system,!1)});let r={model:t.model||void 0,messages:n,max_tokens:t.maxTokens||void 0,stream:!0,stream_options:{include_usage:!0},temperature:t.temperature??0,tools:o(t.tools)},u=await m(e,t.action||`compose-changes`);u[`Content-Type`]=`application/json`,u.Accept=`text/event-stream`,t.conversationId&&(u[`GK-Conversation-ID`]=t.conversationId);let d=await(e.fetch??globalThis.fetch)(f(e,`/chat/completions`),{method:`POST`,redirect:`manual`,headers:u,body:JSON.stringify(r),signal:t.signal}),p=await d.text();if(!d.ok)throw await i(d.status,p,e);let h=l(p);return _(e,h.gk),e.telemetry?.event(`ai.generate`,{provider:`gitkraken`,kind:`chat`}),{text:h.content,toolCalls:h.toolCalls.length>0?h.toolCalls:void 0,usage:h.promptTokens||h.completionTokens||h.totalTokens?{inputTokens:h.promptTokens,outputTokens:h.completionTokens}:void 0,finishReason:c(h.finishReason),rawFinishReason:h.finishReason,...h.model?{model:h.model}:{}}}catch(t){throw e.telemetry?.exception(t,{provider:`gitkraken`,kind:`chat`}),n(t,`AI request failed`)}}function y(e){return{async generate(t){let n=t.messages,r=`tools`in t?t.tools:void 0;return v(e,{model:e.model,conversationId:e.conversationId,system:t.system,messages:n,tools:r,maxTokens:t.maxTokens,temperature:t.temperature,signal:t.signal})}}}async function b(t,a){try{let n=t.request??u,o={taskType:d,action:a.action,messages:[{content:a.prompt}],model:(a.model??t.model)||void 0},s={...await m(t,a.action),"Content-Type":`application/json`},c=performance.now(),l=await n({method:`POST`,url:f(t),headers:s,body:o,signal:a.signal}),p=Math.max(0,Math.round(performance.now()-c));if(!(l.status>=200&&l.status<300))throw await i(l.status,h(l.body),t);let v=g(l.body);if(!S(v))throw C(`task`);let y=v.error;if(y!=null){let t=r(v);throw new e(`provider_error`,`AI request failed: ${S(y)&&typeof y.message==`string`?y.message:`unknown provider error`}`,t)}let b=v.data;if(!S(b))throw C(`task`);if(b.status===`error`||b.status===`failed`)throw new e(`provider_error`,`AI task failed: ${String(b.status)}`,{...r(b),...typeof b.code==`string`?{providerErrorCode:b.code}:{},...typeof b.type==`string`?{providerErrorType:b.type}:{}});if(!S(b.result)||typeof b.result.content!=`string`)throw C(`task`);let x=b.result.content,w=b,T=w.usage;return _(t,T?.gk),t.telemetry?.event(`ai.generate`,{provider:`gitkraken`,kind:`task`,action:a.action,duration_ms:p}),{text:x,...T?.modelId?{model:T.modelId}:{},...w.id?{task:{id:w.id,...w.status?{status:w.status}:{},...w.provider?{provider:w.provider}:{}}}:{},...T?.promptTokens||T?.completionTokens?{usage:{inputTokens:T.promptTokens??0,outputTokens:T.completionTokens??0}}:{}}}catch(e){throw t.telemetry?.exception(e,{provider:`gitkraken`,kind:`task`}),n(e,`AI request failed`)}}async function x(t,a){let o=t.request??u,s;try{let e=await o({method:`GET`,url:f(t,`/providers/${a||d}`),headers:await m(t,void 0)});if(!(e.status>=200&&e.status<300))throw await i(e.status,h(e.body),t);s=g(e.body)}catch(e){throw n(e,`failed to list AI models`)}if(!S(s))throw C(`model list`);if(s.error!=null)throw new e(`provider_error`,`AI model list request returned an error response`,r(s));if(!Array.isArray(s.data))throw C(`model list`);return s.data.map(e=>{if(!S(e)||typeof e.providerId!=`string`||!e.providerId||typeof e.modelId!=`string`||!e.modelId||e.providerName!==void 0&&typeof e.providerName!=`string`||e.modelName!==void 0&&typeof e.modelName!=`string`||e.consumptionRateLabel!==void 0&&typeof e.consumptionRateLabel!=`string`||e.maxInputTokens!==void 0&&typeof e.maxInputTokens!=`number`||e.maxOutputTokens!==void 0&&typeof e.maxOutputTokens!=`number`||e.preferred!==void 0&&typeof e.preferred!=`boolean`)throw C(`model list`);let t=e;return{providerId:t.providerId,providerName:t.providerName,modelId:t.modelId,modelName:t.modelName,maxInputTokens:t.maxInputTokens,maxOutputTokens:t.maxOutputTokens,preferred:t.preferred??!1,consumptionRateLabel:t.consumptionRateLabel}})}function S(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function C(t){return new e(`provider_error`,`AI service returned an invalid ${t} response`)}export{v as chatComplete,y as createGitKrakenModel,x as listModels,b as taskComplete};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gitkraken/ai-provider-tools",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "AI text generation for GitKraken client SDKs: GitKraken-hosted and BYOK (Anthropic, OpenAI, OpenRouter, Ollama) providers behind one model port.",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"author": "Axosoft, LLC dba GitKraken",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"@types/node": "^22.0.0",
|
|
37
37
|
"typescript": "^6.0.2",
|
|
38
38
|
"vitest": "^4.1.1",
|
|
39
|
-
"@gitkraken/conflict-tools": "0.
|
|
39
|
+
"@gitkraken/conflict-tools": "0.8.0"
|
|
40
40
|
},
|
|
41
41
|
"scripts": {
|
|
42
42
|
"build": "tsdown --config-loader=unrun",
|