VSCode extension: import agent lib. (#144)

add-tracing
Zhiming Ma 2023-05-25 00:21:38 +08:00 committed by GitHub
parent ea0252c17d
commit c08f5acf26
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 8691 additions and 888 deletions

7
clients/tabby-agent/dist/cli.js vendored Executable file

File diff suppressed because one or more lines are too long

144
clients/tabby-agent/dist/index.d.ts vendored Normal file
View File

@ -0,0 +1,144 @@
import { EventEmitter } from 'events';
type ApiRequestOptions = {
readonly method: 'GET' | 'PUT' | 'POST' | 'DELETE' | 'OPTIONS' | 'HEAD' | 'PATCH';
readonly url: string;
readonly path?: Record<string, any>;
readonly cookies?: Record<string, any>;
readonly headers?: Record<string, any>;
readonly query?: Record<string, any>;
readonly formData?: Record<string, any>;
readonly body?: any;
readonly mediaType?: string;
readonly responseHeader?: string;
readonly errors?: Record<number, string>;
};
declare class CancelError extends Error {
constructor(message: string);
get isCancelled(): boolean;
}
interface OnCancel {
readonly isResolved: boolean;
readonly isRejected: boolean;
readonly isCancelled: boolean;
(cancelHandler: () => void): void;
}
declare class CancelablePromise<T> implements Promise<T> {
#private;
constructor(executor: (resolve: (value: T | PromiseLike<T>) => void, reject: (reason?: any) => void, onCancel: OnCancel) => void);
get [Symbol.toStringTag](): string;
then<TResult1 = T, TResult2 = never>(onFulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null, onRejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null): Promise<TResult1 | TResult2>;
catch<TResult = never>(onRejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null): Promise<T | TResult>;
finally(onFinally?: (() => void) | null): Promise<T>;
cancel(): void;
get isCancelled(): boolean;
}
/**
* An enumeration.
*/
declare enum EventType {
COMPLETION = "completion",
VIEW = "view",
SELECT = "select"
}
type ChoiceEvent = {
type: EventType;
completion_id: string;
choice_index: number;
};
type Choice = {
index: number;
text: string;
};
type CompletionEvent = {
type: EventType;
id: string;
language: string;
prompt: string;
created: number;
choices: Array<Choice>;
};
type CompletionRequest = {
/**
* Language for completion request
*/
language?: string;
/**
* The context to generate completions for, encoded as a string.
*/
prompt: string;
};
type CompletionResponse = {
id: string;
created: number;
choices: Array<Choice>;
};
type ApiResult = {
readonly url: string;
readonly ok: boolean;
readonly status: number;
readonly statusText: string;
readonly body: any;
};
declare class ApiError extends Error {
readonly url: string;
readonly status: number;
readonly statusText: string;
readonly body: any;
readonly request: ApiRequestOptions;
constructor(request: ApiRequestOptions, response: ApiResult, message: string);
}
type ValidationError = {
loc: Array<(string | number)>;
msg: string;
type: string;
};
type HTTPValidationError = {
detail?: Array<ValidationError>;
};
interface AgentFunction {
setServerUrl(url: string): string;
getServerUrl(): string;
getStatus(): "connecting" | "ready" | "disconnected";
getCompletions(request: CompletionRequest): CancelablePromise<CompletionResponse>;
postEvent(event: ChoiceEvent | CompletionEvent): CancelablePromise<any>;
}
type StatusChangedEvent = {
event: "statusChanged";
status: "connecting" | "ready" | "disconnected";
};
type AgentEvent = StatusChangedEvent;
declare const agentEventNames: AgentEvent['event'][];
interface AgentEventEmitter {
on<T extends AgentEvent>(eventName: T["event"], callback: (event: T) => void): this;
}
type Agent = AgentFunction & AgentEventEmitter;
declare class TabbyAgent extends EventEmitter implements Agent {
private serverUrl;
private status;
private api;
constructor();
private changeStatus;
private ping;
private wrapApiPromise;
setServerUrl(serverUrl: string): string;
getServerUrl(): string;
getStatus(): "connecting" | "ready" | "disconnected";
getCompletions(request: CompletionRequest): CancelablePromise<CompletionResponse>;
postEvent(request: ChoiceEvent | CompletionEvent): CancelablePromise<any>;
}
export { Agent, AgentEvent, AgentFunction, ApiError, CancelError, CancelablePromise, Choice, ChoiceEvent, CompletionEvent, CompletionRequest, CompletionResponse, EventType, HTTPValidationError, StatusChangedEvent, TabbyAgent, ValidationError, agentEventNames };

7099
clients/tabby-agent/dist/index.global.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

582
clients/tabby-agent/dist/index.js vendored Normal file
View File

@ -0,0 +1,582 @@
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var __accessCheck = (obj, member, msg) => {
if (!member.has(obj))
throw TypeError("Cannot " + msg);
};
var __privateGet = (obj, member, getter) => {
__accessCheck(obj, member, "read from private field");
return getter ? getter.call(obj) : member.get(obj);
};
var __privateAdd = (obj, member, value) => {
if (member.has(obj))
throw TypeError("Cannot add the same private member more than once");
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
};
var __privateSet = (obj, member, value, setter) => {
__accessCheck(obj, member, "write to private field");
setter ? setter.call(obj, value) : member.set(obj, value);
return value;
};
// src/index.ts
var src_exports = {};
__export(src_exports, {
ApiError: () => ApiError,
CancelError: () => CancelError,
CancelablePromise: () => CancelablePromise,
EventType: () => EventType,
TabbyAgent: () => TabbyAgent,
agentEventNames: () => agentEventNames
});
module.exports = __toCommonJS(src_exports);
// src/TabbyAgent.ts
var import_axios2 = __toESM(require("axios"));
var import_events = require("events");
var import_assert = require("assert");
// src/utils.ts
function sleep(milliseconds) {
return new Promise((r) => setTimeout(r, milliseconds));
}
// src/generated/core/BaseHttpRequest.ts
var BaseHttpRequest = class {
constructor(config) {
this.config = config;
}
};
// src/generated/core/request.ts
var import_axios = __toESM(require("axios"));
var import_form_data = __toESM(require("form-data"));
// src/generated/core/ApiError.ts
var ApiError = class extends Error {
constructor(request2, response, message) {
super(message);
this.name = "ApiError";
this.url = response.url;
this.status = response.status;
this.statusText = response.statusText;
this.body = response.body;
this.request = request2;
}
};
// src/generated/core/CancelablePromise.ts
var CancelError = class extends Error {
constructor(message) {
super(message);
this.name = "CancelError";
}
get isCancelled() {
return true;
}
};
var _isResolved, _isRejected, _isCancelled, _cancelHandlers, _promise, _resolve, _reject;
var CancelablePromise = class {
constructor(executor) {
__privateAdd(this, _isResolved, void 0);
__privateAdd(this, _isRejected, void 0);
__privateAdd(this, _isCancelled, void 0);
__privateAdd(this, _cancelHandlers, void 0);
__privateAdd(this, _promise, void 0);
__privateAdd(this, _resolve, void 0);
__privateAdd(this, _reject, void 0);
__privateSet(this, _isResolved, false);
__privateSet(this, _isRejected, false);
__privateSet(this, _isCancelled, false);
__privateSet(this, _cancelHandlers, []);
__privateSet(this, _promise, new Promise((resolve2, reject) => {
__privateSet(this, _resolve, resolve2);
__privateSet(this, _reject, reject);
const onResolve = (value) => {
var _a;
if (__privateGet(this, _isResolved) || __privateGet(this, _isRejected) || __privateGet(this, _isCancelled)) {
return;
}
__privateSet(this, _isResolved, true);
(_a = __privateGet(this, _resolve)) == null ? void 0 : _a.call(this, value);
};
const onReject = (reason) => {
var _a;
if (__privateGet(this, _isResolved) || __privateGet(this, _isRejected) || __privateGet(this, _isCancelled)) {
return;
}
__privateSet(this, _isRejected, true);
(_a = __privateGet(this, _reject)) == null ? void 0 : _a.call(this, reason);
};
const onCancel = (cancelHandler) => {
if (__privateGet(this, _isResolved) || __privateGet(this, _isRejected) || __privateGet(this, _isCancelled)) {
return;
}
__privateGet(this, _cancelHandlers).push(cancelHandler);
};
Object.defineProperty(onCancel, "isResolved", {
get: () => __privateGet(this, _isResolved)
});
Object.defineProperty(onCancel, "isRejected", {
get: () => __privateGet(this, _isRejected)
});
Object.defineProperty(onCancel, "isCancelled", {
get: () => __privateGet(this, _isCancelled)
});
return executor(onResolve, onReject, onCancel);
}));
}
get [Symbol.toStringTag]() {
return "Cancellable Promise";
}
then(onFulfilled, onRejected) {
return __privateGet(this, _promise).then(onFulfilled, onRejected);
}
catch(onRejected) {
return __privateGet(this, _promise).catch(onRejected);
}
finally(onFinally) {
return __privateGet(this, _promise).finally(onFinally);
}
cancel() {
var _a;
if (__privateGet(this, _isResolved) || __privateGet(this, _isRejected) || __privateGet(this, _isCancelled)) {
return;
}
__privateSet(this, _isCancelled, true);
if (__privateGet(this, _cancelHandlers).length) {
try {
for (const cancelHandler of __privateGet(this, _cancelHandlers)) {
cancelHandler();
}
} catch (error) {
console.warn("Cancellation threw an error", error);
return;
}
}
__privateGet(this, _cancelHandlers).length = 0;
(_a = __privateGet(this, _reject)) == null ? void 0 : _a.call(this, new CancelError("Request aborted"));
}
get isCancelled() {
return __privateGet(this, _isCancelled);
}
};
_isResolved = new WeakMap();
_isRejected = new WeakMap();
_isCancelled = new WeakMap();
_cancelHandlers = new WeakMap();
_promise = new WeakMap();
_resolve = new WeakMap();
_reject = new WeakMap();
// src/generated/core/request.ts
var isDefined = (value) => {
return value !== void 0 && value !== null;
};
var isString = (value) => {
return typeof value === "string";
};
var isStringWithValue = (value) => {
return isString(value) && value !== "";
};
var isBlob = (value) => {
return typeof value === "object" && typeof value.type === "string" && typeof value.stream === "function" && typeof value.arrayBuffer === "function" && typeof value.constructor === "function" && typeof value.constructor.name === "string" && /^(Blob|File)$/.test(value.constructor.name) && /^(Blob|File)$/.test(value[Symbol.toStringTag]);
};
var isFormData = (value) => {
return value instanceof import_form_data.default;
};
var isSuccess = (status) => {
return status >= 200 && status < 300;
};
var base64 = (str) => {
try {
return btoa(str);
} catch (err) {
return Buffer.from(str).toString("base64");
}
};
var getQueryString = (params) => {
const qs = [];
const append = (key, value) => {
qs.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`);
};
const process = (key, value) => {
if (isDefined(value)) {
if (Array.isArray(value)) {
value.forEach((v) => {
process(key, v);
});
} else if (typeof value === "object") {
Object.entries(value).forEach(([k, v]) => {
process(`${key}[${k}]`, v);
});
} else {
append(key, value);
}
}
};
Object.entries(params).forEach(([key, value]) => {
process(key, value);
});
if (qs.length > 0) {
return `?${qs.join("&")}`;
}
return "";
};
var getUrl = (config, options) => {
const encoder = config.ENCODE_PATH || encodeURI;
const path = options.url.replace("{api-version}", config.VERSION).replace(/{(.*?)}/g, (substring, group) => {
if (options.path?.hasOwnProperty(group)) {
return encoder(String(options.path[group]));
}
return substring;
});
const url = `${config.BASE}${path}`;
if (options.query) {
return `${url}${getQueryString(options.query)}`;
}
return url;
};
var getFormData = (options) => {
if (options.formData) {
const formData = new import_form_data.default();
const process = (key, value) => {
if (isString(value) || isBlob(value)) {
formData.append(key, value);
} else {
formData.append(key, JSON.stringify(value));
}
};
Object.entries(options.formData).filter(([_, value]) => isDefined(value)).forEach(([key, value]) => {
if (Array.isArray(value)) {
value.forEach((v) => process(key, v));
} else {
process(key, value);
}
});
return formData;
}
return void 0;
};
var resolve = async (options, resolver) => {
if (typeof resolver === "function") {
return resolver(options);
}
return resolver;
};
var getHeaders = async (config, options, formData) => {
const token = await resolve(options, config.TOKEN);
const username = await resolve(options, config.USERNAME);
const password = await resolve(options, config.PASSWORD);
const additionalHeaders = await resolve(options, config.HEADERS);
const formHeaders = typeof formData?.getHeaders === "function" && formData?.getHeaders() || {};
const headers = Object.entries({
Accept: "application/json",
...additionalHeaders,
...options.headers,
...formHeaders
}).filter(([_, value]) => isDefined(value)).reduce((headers2, [key, value]) => ({
...headers2,
[key]: String(value)
}), {});
if (isStringWithValue(token)) {
headers["Authorization"] = `Bearer ${token}`;
}
if (isStringWithValue(username) && isStringWithValue(password)) {
const credentials = base64(`${username}:${password}`);
headers["Authorization"] = `Basic ${credentials}`;
}
if (options.body) {
if (options.mediaType) {
headers["Content-Type"] = options.mediaType;
} else if (isBlob(options.body)) {
headers["Content-Type"] = options.body.type || "application/octet-stream";
} else if (isString(options.body)) {
headers["Content-Type"] = "text/plain";
} else if (!isFormData(options.body)) {
headers["Content-Type"] = "application/json";
}
}
return headers;
};
var getRequestBody = (options) => {
if (options.body) {
return options.body;
}
return void 0;
};
var sendRequest = async (config, options, url, body, formData, headers, onCancel) => {
const source = import_axios.default.CancelToken.source();
const requestConfig = {
url,
headers,
data: body ?? formData,
method: options.method,
withCredentials: config.WITH_CREDENTIALS,
cancelToken: source.token
};
onCancel(() => source.cancel("The user aborted a request."));
try {
return await import_axios.default.request(requestConfig);
} catch (error) {
const axiosError = error;
if (axiosError.response) {
return axiosError.response;
}
throw error;
}
};
var getResponseHeader = (response, responseHeader) => {
if (responseHeader) {
const content = response.headers[responseHeader];
if (isString(content)) {
return content;
}
}
return void 0;
};
var getResponseBody = (response) => {
if (response.status !== 204) {
return response.data;
}
return void 0;
};
var catchErrorCodes = (options, result) => {
const errors = {
400: "Bad Request",
401: "Unauthorized",
403: "Forbidden",
404: "Not Found",
500: "Internal Server Error",
502: "Bad Gateway",
503: "Service Unavailable",
...options.errors
};
const error = errors[result.status];
if (error) {
throw new ApiError(options, result, error);
}
if (!result.ok) {
throw new ApiError(options, result, "Generic Error");
}
};
var request = (config, options) => {
return new CancelablePromise(async (resolve2, reject, onCancel) => {
try {
const url = getUrl(config, options);
const formData = getFormData(options);
const body = getRequestBody(options);
const headers = await getHeaders(config, options, formData);
if (!onCancel.isCancelled) {
const response = await sendRequest(config, options, url, body, formData, headers, onCancel);
const responseBody = getResponseBody(response);
const responseHeader = getResponseHeader(response, options.responseHeader);
const result = {
url,
ok: isSuccess(response.status),
status: response.status,
statusText: response.statusText,
body: responseHeader ?? responseBody
};
catchErrorCodes(options, result);
resolve2(result.body);
}
} catch (error) {
reject(error);
}
});
};
// src/generated/core/AxiosHttpRequest.ts
var AxiosHttpRequest = class extends BaseHttpRequest {
constructor(config) {
super(config);
}
/**
* Request method
* @param options The request options from the service
* @returns CancelablePromise<T>
* @throws ApiError
*/
request(options) {
return request(this.config, options);
}
};
// src/generated/services/DefaultService.ts
var DefaultService = class {
constructor(httpRequest) {
this.httpRequest = httpRequest;
}
/**
* Completions
* @param requestBody
* @returns CompletionResponse Successful Response
* @throws ApiError
*/
completionsV1CompletionsPost(requestBody) {
return this.httpRequest.request({
method: "POST",
url: "/v1/completions",
body: requestBody,
mediaType: "application/json",
errors: {
422: `Validation Error`
}
});
}
/**
* Events
* @param requestBody
* @returns any Successful Response
* @throws ApiError
*/
eventsV1EventsPost(requestBody) {
return this.httpRequest.request({
method: "POST",
url: "/v1/events",
body: requestBody,
mediaType: "application/json",
errors: {
422: `Validation Error`
}
});
}
};
// src/generated/TabbyApi.ts
var TabbyApi = class {
constructor(config, HttpRequest = AxiosHttpRequest) {
this.request = new HttpRequest({
BASE: config?.BASE ?? "",
VERSION: config?.VERSION ?? "0.1.0",
WITH_CREDENTIALS: config?.WITH_CREDENTIALS ?? false,
CREDENTIALS: config?.CREDENTIALS ?? "include",
TOKEN: config?.TOKEN,
USERNAME: config?.USERNAME,
PASSWORD: config?.PASSWORD,
HEADERS: config?.HEADERS,
ENCODE_PATH: config?.ENCODE_PATH
});
this.default = new DefaultService(this.request);
}
};
// src/generated/models/EventType.ts
var EventType = /* @__PURE__ */ ((EventType2) => {
EventType2["COMPLETION"] = "completion";
EventType2["VIEW"] = "view";
EventType2["SELECT"] = "select";
return EventType2;
})(EventType || {});
// src/TabbyAgent.ts
var TabbyAgent = class extends import_events.EventEmitter {
constructor() {
super();
this.serverUrl = "http://127.0.0.1:5000";
this.status = "connecting";
this.ping();
this.api = new TabbyApi({ BASE: this.serverUrl });
}
changeStatus(status) {
if (this.status != status) {
this.status = status;
const event = { event: "statusChanged", status };
super.emit("statusChanged", event);
}
}
async ping(tries = 0) {
try {
const response = await import_axios2.default.get(`${this.serverUrl}/`);
(0, import_assert.strict)(response.status == 200);
this.changeStatus("ready");
return true;
} catch (e) {
if (tries > 5) {
this.changeStatus("disconnected");
return false;
}
this.changeStatus("connecting");
const pingRetryDelay = 1e3;
await sleep(pingRetryDelay);
return this.ping(tries + 1);
}
}
wrapApiPromise(promise) {
return new CancelablePromise((resolve2, reject, onCancel) => {
promise.then((resp) => {
this.changeStatus("ready");
resolve2(resp);
}).catch((err) => {
reject(err);
}).catch((err) => {
this.changeStatus("disconnected");
reject(err);
}).catch((err) => {
reject(err);
});
onCancel(() => {
promise.cancel();
});
});
}
setServerUrl(serverUrl) {
this.serverUrl = serverUrl.replace(/\/$/, "");
this.ping();
this.api = new TabbyApi({ BASE: this.serverUrl });
return this.serverUrl;
}
getServerUrl() {
return this.serverUrl;
}
getStatus() {
return this.status;
}
getCompletions(request2) {
const promise = this.api.default.completionsV1CompletionsPost(request2);
return this.wrapApiPromise(promise);
}
postEvent(request2) {
const promise = this.api.default.eventsV1EventsPost(request2);
return this.wrapApiPromise(promise);
}
};
// src/types.ts
var agentEventNames = ["statusChanged"];
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
ApiError,
CancelError,
CancelablePromise,
EventType,
TabbyAgent,
agentEventNames
});
//# sourceMappingURL=index.js.map

1
clients/tabby-agent/dist/index.js.map vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,13 +0,0 @@
/*!
* mime-db
* Copyright(c) 2014 Jonathan Ong
* Copyright(c) 2015-2022 Douglas Christopher Wilson
* MIT Licensed
*/
/*!
* mime-types
* Copyright(c) 2014 Jonathan Ong
* Copyright(c) 2015 Douglas Christopher Wilson
* MIT Licensed
*/

View File

@ -3,19 +3,31 @@
"version": "0.0.1",
"description": "Generic client agent for Tabby AI coding assistant IDE extensions.",
"repository": "https://github.com/TabbyML/tabby",
"files": [
"dist"
],
"main": "./dist/index.js",
"browser": "./dist/index.global.js",
"types": "./dist/index.d.ts",
"exports": {
"require": "./dist/index.js",
"types": "./dist/index.d.ts"
},
"scripts": {
"openapi-codegen": "rimraf ./src/generated && openapi --input ../../docs/openapi.json --output ./src/generated --client axios --name TabbyApi --indent 2",
"dev": "webpack --watch",
"build": "webpack --mode=production"
"dev": "tsup --watch",
"build": "tsup"
},
"devDependencies": {
"axios": "^1.3.4",
"form-data": "^4.0.0",
"@types/node": "^16.18.32",
"esbuild-plugin-polyfill-node": "^0.2.0",
"openapi-typescript-codegen": "^0.24.0",
"rimraf": "^5.0.1",
"ts-loader": "^9.4.2",
"typescript": "^5.0.3",
"webpack": "^5.77.0",
"webpack-cli": "^5.0.1"
"tsup": "^6.7.0",
"typescript": "^5.0.3"
},
"dependencies": {
"axios": "^1.4.0",
"form-data": "^4.0.0"
}
}

View File

@ -1,5 +1,5 @@
import { CancelablePromise } from "./generated";
import { AgentFunction, AgentEvent, Agent, AgentIO, agentEventNames } from "./types";
import { AgentFunction, AgentEvent, Agent, agentEventNames } from "./types";
import { splitLines } from "./utils";
type AgentFunctionRequest<T extends keyof AgentFunction> = [
@ -38,10 +38,9 @@ type CancellationResponse = [
type Response = AgentFunctionResponse<any> | AgentEventNotification | CancellationResponse;
/**
* This class implements the AgentIO interface using stdio.
* Every request and response should be single line JSON string and end with a newline.
*/
export class StdIO implements AgentIO {
export class StdIO {
private readonly inStream: NodeJS.ReadStream = process.stdin;
private readonly outStream: NodeJS.WriteStream = process.stdout;
private readonly errLogger: NodeJS.WriteStream = process.stderr;

View File

@ -1,6 +1,6 @@
import axios from "axios";
import { EventEmitter } from "node:events";
import { strict as assert } from "node:assert";
import { EventEmitter } from "events";
import { strict as assert } from "assert";
import { sleep } from "./utils";
import { Agent, AgentEvent } from "./types";
import {
@ -29,7 +29,7 @@ export class TabbyAgent extends EventEmitter implements Agent {
if (this.status != status) {
this.status = status;
const event: AgentEvent = { event: "statusChanged", status };
this.emit("statusChanged", event);
super.emit("statusChanged", event);
}
}
@ -85,6 +85,10 @@ export class TabbyAgent extends EventEmitter implements Agent {
return this.serverUrl;
}
public getStatus(): "connecting" | "ready" | "disconnected" {
return this.status;
}
public getCompletions(request: CompletionRequest): CancelablePromise<CompletionResponse> {
const promise = this.api.default.completionsV1CompletionsPost(request);
return this.wrapApiPromise(promise);

View File

@ -0,0 +1,9 @@
#!/bin/env node
import { TabbyAgent } from "./TabbyAgent";
import { StdIO } from "./StdIO";
const agent = new TabbyAgent();
const stdio = new StdIO();
stdio.bind(agent);
stdio.listen();

View File

@ -1,7 +1,15 @@
import { TabbyAgent } from "./TabbyAgent";
import { StdIO } from "./StdIO";
const agent = new TabbyAgent();
const stdio = new StdIO();
stdio.bind(agent);
stdio.listen();
export { TabbyAgent } from "./TabbyAgent";
export { Agent, AgentFunction, AgentEvent, StatusChangedEvent, agentEventNames } from "./types";
export {
CancelablePromise,
CancelError,
ApiError,
HTTPValidationError,
ValidationError,
CompletionRequest,
CompletionResponse,
Choice,
ChoiceEvent,
CompletionEvent,
EventType,
} from "./generated";

View File

@ -3,11 +3,12 @@ import { CancelablePromise, ChoiceEvent, CompletionEvent, CompletionRequest, Com
export interface AgentFunction {
setServerUrl(url: string): string;
getServerUrl(): string;
getStatus(): "connecting" | "ready" | "disconnected";
getCompletions(request: CompletionRequest): CancelablePromise<CompletionResponse>;
postEvent(event: ChoiceEvent | CompletionEvent): CancelablePromise<boolean>;
postEvent(event: ChoiceEvent | CompletionEvent): CancelablePromise<any>;
}
type StatusChangedEvent = {
export type StatusChangedEvent = {
event: "statusChanged";
status: "connecting" | "ready" | "disconnected";
}
@ -20,8 +21,3 @@ export interface AgentEventEmitter {
}
export type Agent = AgentFunction & AgentEventEmitter;
export interface AgentIO {
bind(agent: Agent): void;
listen(): void;
}

View File

@ -5,5 +5,6 @@
"lib": ["ES2020", "dom"],
"sourceMap": true,
"allowSyntheticDefaultImports": true
}
},
"include": ["./src"]
}

View File

@ -0,0 +1,38 @@
import { defineConfig } from "tsup";
import { polyfillNode } from "esbuild-plugin-polyfill-node";
export default [
defineConfig({
name: "lib-node",
entry: ["src/index.ts"],
platform: "node",
format: ["cjs"],
sourcemap: true,
clean: true,
}),
defineConfig({
name: "lib-browser",
entry: ["src/index.ts"],
platform: "browser",
format: ["iife"],
globalName: "Tabby",
sourcemap: true,
esbuildPlugins: [polyfillNode()],
clean: true,
}),
defineConfig({
name: "lib-typedefs",
entry: ["src/index.ts"],
dts: {
only: true,
},
clean: true,
}),
defineConfig({
name: "cli",
entry: ["src/cli.ts"],
platform: "node",
minify: true,
clean: true,
}),
];

View File

@ -1,28 +0,0 @@
const path = require('path');
module.exports = {
target: 'node',
mode: 'none',
output: {
filename: 'tabby-agent.js',
path: path.resolve(__dirname, 'dist'),
},
entry: './src/index.ts',
resolve: {
extensions: ['.ts', '.js'],
preferRelative: true,
},
module: {
rules: [
{
test: /\.ts$/,
exclude: /node_modules/,
use: [
{
loader: 'ts-loader'
}
]
}
]
},
};

File diff suppressed because it is too large Load Diff

View File

@ -193,7 +193,7 @@ function! tabby#Start()
let tabby_root = expand('<sfile>:h:h')
let node_script = tabby_root . '/node_scripts/tabby-agent.js'
if !filereadable(node_script)
let s:errmsg = 'Tabby node script should be download first. Try to run `yarn install`.'
let s:errmsg = 'Tabby node script should be download first. Try to run `yarn upgrade-agent`.'
return
endif

9
clients/vim/node_scripts/tabby-agent.js Normal file → Executable file

File diff suppressed because one or more lines are too long

View File

@ -1,13 +0,0 @@
/*!
* mime-db
* Copyright(c) 2014 Jonathan Ong
* Copyright(c) 2015-2022 Douglas Christopher Wilson
* MIT Licensed
*/
/*!
* mime-types
* Copyright(c) 2014 Jonathan Ong
* Copyright(c) 2015 Douglas Christopher Wilson
* MIT Licensed
*/

View File

@ -4,8 +4,7 @@
"description": "Vim plugin for Tabby AI coding assistant.",
"repository": "https://github.com/TabbyML/tabby",
"scripts": {
"postinstall": "yarn copy-scripts",
"copy-scripts": "rimraf ./node_scripts && cpy --cwd='node_modules/tabby-agent/dist' ./ ../../../node_scripts/"
"upgrade-agent": "yarn upgrade tabby-agent && rimraf ./node_scripts && cpy node_modules/tabby-agent/dist/cli.js ./node_scripts/ --flat --rename=tabby-agent.js"
},
"devDependencies": {
"cpy-cli": "^4.2.0",

View File

@ -118,6 +118,20 @@ arrify@^3.0.0:
resolved "https://registry.yarnpkg.com/arrify/-/arrify-3.0.0.tgz#ccdefb8eaf2a1d2ab0da1ca2ce53118759fd46bc"
integrity sha512-tLkvA81vQG/XqE2mjDkGQHoOINtMHtysSnemrmoGe6PydDPMRbVugqyk4A6V/WDWEfm3l+0d8anA9r8cv/5Jaw==
asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==
axios@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/axios/-/axios-1.4.0.tgz#38a7bf1224cd308de271146038b551d725f0be1f"
integrity sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==
dependencies:
follow-redirects "^1.15.0"
form-data "^4.0.0"
proxy-from-env "^1.1.0"
balanced-match@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
@ -192,6 +206,13 @@ color-name@~1.1.4:
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
combined-stream@^1.0.8:
version "1.0.8"
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
dependencies:
delayed-stream "~1.0.0"
cp-file@^9.1.0:
version "9.1.0"
resolved "https://registry.yarnpkg.com/cp-file/-/cp-file-9.1.0.tgz#e98e30db72d57d47b5b1d444deb70d05e5684921"
@ -251,6 +272,11 @@ decamelize@^5.0.0:
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-5.0.1.tgz#db11a92e58c741ef339fb0a2868d8a06a9a7b1e9"
integrity sha512-VfxadyCECXgQlkoEAjeghAr5gY3Hf+IKjKb+X8tGVDtveCjN+USwprd2q3QXBR9T1+x2DG0XZF5/w+7HAtSaXA==
delayed-stream@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==
dir-glob@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f"
@ -323,6 +349,11 @@ find-up@^5.0.0:
locate-path "^6.0.0"
path-exists "^4.0.0"
follow-redirects@^1.15.0:
version "1.15.2"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13"
integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==
foreground-child@^3.1.0:
version "3.1.1"
resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.1.1.tgz#1d173e776d75d2772fed08efe4a0de1ea1b12d0d"
@ -331,6 +362,15 @@ foreground-child@^3.1.0:
cross-spawn "^7.0.0"
signal-exit "^4.0.1"
form-data@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452"
integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==
dependencies:
asynckit "^0.4.0"
combined-stream "^1.0.8"
mime-types "^2.1.12"
function-bind@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
@ -549,6 +589,18 @@ micromatch@^4.0.4:
braces "^3.0.2"
picomatch "^2.3.1"
mime-db@1.52.0:
version "1.52.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70"
integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
mime-types@^2.1.12:
version "2.1.35"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a"
integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
dependencies:
mime-db "1.52.0"
min-indent@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869"
@ -675,6 +727,11 @@ picomatch@^2.3.1:
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
proxy-from-env@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==
queue-microtask@^1.2.2:
version "1.2.3"
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
@ -841,6 +898,9 @@ supports-color@^5.3.0:
"tabby-agent@file:../tabby-agent":
version "0.0.1"
dependencies:
axios "^1.4.0"
form-data "^4.0.0"
to-regex-range@^5.0.1:
version "5.0.1"

View File

@ -67,8 +67,6 @@
}
},
"scripts": {
"postinstall": "yarn openapi-codegen",
"openapi-codegen": "openapi --input ../../docs/openapi.json --output ./src/generated --client axios --name Tabby --indent 2",
"vscode:prepublish": "yarn package",
"compile": "webpack",
"watch": "webpack --watch",
@ -91,10 +89,12 @@
"@typescript-eslint/eslint-plugin": "^5.31.0",
"@typescript-eslint/parser": "^5.31.0",
"@vscode/test-electron": "^2.1.5",
"assert": "^2.0.0",
"eslint": "^8.20.0",
"glob": "^8.0.3",
"mocha": "^10.0.0",
"openapi-typescript-codegen": "^0.24.0",
"process": "^0.11.10",
"ts-loader": "^9.3.1",
"typescript": "^4.7.4",
"vsce": "^2.15.0",
@ -103,11 +103,7 @@
},
"dependencies": {
"@sapphire/duration": "^1.1.0",
"assert": "^2.0.0",
"axios": "^1.3.4",
"events": "^3.3.0",
"form-data": "^4.0.0",
"linked-list-typescript": "^1.0.15",
"process": "^0.11.10"
"tabby-agent": "file:../tabby-agent"
}
}

View File

@ -0,0 +1,28 @@
import { workspace } from "vscode";
import { TabbyAgent } from "tabby-agent";
export class Agent extends TabbyAgent {
private static instance: Agent;
static getInstance(): Agent {
if (!Agent.instance) {
Agent.instance = new Agent();
}
return Agent.instance;
}
private constructor() {
super();
this.updateConfiguration();
workspace.onDidChangeConfiguration((event) => {
if (event.affectsConfiguration("tabby")) {
this.updateConfiguration();
}
});
}
private updateConfiguration() {
const configuration = workspace.getConfiguration("tabby");
const serverUrl = configuration.get("serverUrl", "http://localhost:5000");
this.setServerUrl(serverUrl);
}
}

View File

@ -7,10 +7,10 @@ import {
window,
commands,
} from "vscode";
import { strict as assert } from "assert";
import { Duration } from "@sapphire/duration";
import { ChoiceEvent, ApiError } from "./generated";
import { TabbyClient } from "./TabbyClient";
import { strict as assert } from "node:assert";
import { ChoiceEvent } from "tabby-agent";
import { Agent } from "./Agent";
const target = ConfigurationTarget.Global;
@ -128,20 +128,12 @@ const openSettings: Command = {
},
};
const tabbyClient = TabbyClient.getInstance();
const agent = Agent.getInstance();
const emitEvent: Command = {
command: "tabby.emitEvent",
callback: (event: ChoiceEvent) => {
console.debug("Emit Event: ", event);
tabbyClient.api.default
.eventsV1EventsPost(event)
.then(() => {
tabbyClient.changeStatus("ready");
})
.catch((err: ApiError) => {
console.error(err);
tabbyClient.changeStatus("disconnected");
});
agent.postEvent(event);
},
};

View File

@ -1,5 +1,5 @@
import { LinkedList } from "linked-list-typescript";
import { CompletionResponse, Choice } from "./generated";
import { CompletionResponse, Choice } from "tabby-agent";
type Range = {
start: number;
@ -43,7 +43,7 @@ export class CompletionCache {
if (text.slice(entry.promptRange.start, entry.promptRange.end) !== entry.prompt) {
continue;
}
// Filter choices that start with inputed text after prompt
// Filter choices that start with inputted text after prompt
const compatibleChoices = entry.completion.choices
.filter((choice) => choice.text.startsWith(text.slice(entry.promptRange.end, cursor)))
.map((choice) => {

View File

@ -1,65 +0,0 @@
import { workspace } from "vscode";
import axios from "axios";
import { sleep } from "./utils";
import { EventEmitter } from "node:events";
import { strict as assert } from "node:assert";
import { Tabby as TabbyApi } from "./generated";
export class TabbyClient extends EventEmitter {
private static instance: TabbyClient;
static getInstance(): TabbyClient {
if (!TabbyClient.instance) {
TabbyClient.instance = new TabbyClient();
}
return TabbyClient.instance;
}
private serverUrl: string = "";
status: "connecting" | "ready" | "disconnected" = "connecting";
api: TabbyApi;
constructor() {
super();
this.updateConfiguration();
this.api = new TabbyApi({ BASE: this.serverUrl });
workspace.onDidChangeConfiguration((event) => {
if (event.affectsConfiguration("tabby")) {
this.updateConfiguration();
this.api = new TabbyApi({ BASE: this.serverUrl });
}
});
}
private updateConfiguration() {
const configuration = workspace.getConfiguration("tabby");
this.serverUrl = configuration.get("serverUrl", "http://127.0.0.1:5000");
this.serverUrl = this.serverUrl.replace(/\/$/, ''); // Remove trailing slash
this.ping();
}
public changeStatus(status: "connecting" | "ready" | "disconnected") {
if (this.status != status) {
this.status = status;
this.emit("statusChanged", status);
}
}
private async ping(tries: number = 0): Promise<boolean> {
try {
const response = await axios.get(`${this.serverUrl}/`);
assert(response.status == 200);
this.changeStatus("ready");
return true;
} catch (e) {
if (tries > 5) {
this.changeStatus("disconnected");
return false;
}
this.changeStatus("connecting");
const pingRetryDelay = 1000;
await sleep(pingRetryDelay);
return this.ping(tries + 1);
}
}
}

View File

@ -10,8 +10,8 @@ import {
TextDocument,
workspace,
} from "vscode";
import { CompletionResponse, EventType, ChoiceEvent, ApiError, CancelablePromise, CancelError } from "./generated";
import { TabbyClient } from "./TabbyClient";
import { CompletionResponse, EventType, ChoiceEvent, CancelablePromise } from "tabby-agent";
import { Agent } from "./Agent";
import { CompletionCache } from "./CompletionCache";
import { sleep } from "./utils";
@ -20,7 +20,7 @@ export class TabbyCompletionProvider implements InlineCompletionItemProvider {
private latestTimestamp: number = 0;
private pendingCompletion: CancelablePromise<CompletionResponse> | null = null;
private tabbyClient = TabbyClient.getInstance();
private agent = Agent.getInstance();
private completionCache = new CompletionCache();
// User Settings
private enabled: boolean = true;
@ -81,19 +81,12 @@ export class TabbyCompletionProvider implements InlineCompletionItemProvider {
if (this.pendingCompletion) {
this.pendingCompletion.cancel();
}
this.pendingCompletion = this.tabbyClient.api.default.completionsV1CompletionsPost({
this.pendingCompletion = this.agent.getCompletions({
prompt: prompt as string, // Prompt is already nil-checked
language: document.languageId, // https://code.visualstudio.com/docs/languages/identifiers
});
const completion = await this.pendingCompletion.then((response: CompletionResponse) => {
this.tabbyClient.changeStatus("ready");
return response;
}).catch((_: CancelError) => {
return null;
}).catch((err: ApiError) => {
console.error(err);
this.tabbyClient.changeStatus("disconnected");
const completion = await this.pendingCompletion.catch((_: Error) => {
return null;
});
this.pendingCompletion = null;

View File

@ -1,21 +1,21 @@
import { StatusBarAlignment, ThemeColor, window, workspace } from "vscode";
import { TabbyClient } from "./TabbyClient";
import { Agent } from "./Agent";
const label = "Tabby";
const iconLoading = "$(loading~spin)";
const iconReady = "$(check)";
const iconDisconnected = "$(plug)";
const iconDisabled = "$(x)";
const colorNormal = new ThemeColor('statusBar.foreground');
const colorWarning = new ThemeColor('statusBarItem.warningForeground');
const backgroundColorNormal = new ThemeColor('statusBar.background');
const backgroundColorWarning = new ThemeColor('statusBarItem.warningBackground');
const colorNormal = new ThemeColor("statusBar.foreground");
const colorWarning = new ThemeColor("statusBarItem.warningForeground");
const backgroundColorNormal = new ThemeColor("statusBar.background");
const backgroundColorWarning = new ThemeColor("statusBarItem.warningBackground");
const item = window.createStatusBarItem(StatusBarAlignment.Right);
export const tabbyStatusBarItem = item;
const client = TabbyClient.getInstance();
client.on("statusChanged", updateStatusBarItem);
const agent = Agent.getInstance();
agent.on("statusChanged", updateStatusBarItem);
workspace.onDidChangeConfiguration((event) => {
if (event.affectsConfiguration("tabby")) {
@ -31,7 +31,7 @@ function updateStatusBarItem() {
if (!enabled) {
toDisabled();
} else {
const status = client.status;
const status = agent.getStatus();
switch (status) {
case "connecting":
toLoading();

View File

@ -3,13 +3,14 @@
'use strict';
const path = require('path');
const webpack = require("webpack");
const webpack = require('webpack');
//@ts-check
/** @typedef {import('webpack').Configuration} WebpackConfig **/
/** @type WebpackConfig */
const extensionNodeConfig = {
name: 'node',
target: 'node', // VS Code extensions run in a Node.js-context 📖 -> https://webpack.js.org/configuration/node/
mode: 'none', // this leaves the source code as close as possible to the original (when packaging we set this to 'production')
@ -48,6 +49,7 @@ const extensionNodeConfig = {
};
const extensionWebConfig = {
name: 'web',
target: 'webworker', // VS Code extensions run in a Node.js-context 📖 -> https://webpack.js.org/configuration/node/
mode: 'none', // this leaves the source code as close as possible to the original (when packaging we set this to 'production')
@ -70,18 +72,11 @@ const extensionWebConfig = {
// see https://webpack.js.org/configuration/resolve/#resolvefallback
// for the list of Node.js core module polyfills.
assert: require.resolve('assert'),
events: require.resolve('events'),
},
},
plugins: [
new webpack.NormalModuleReplacementPlugin(
/^node:/,
(resource) => {
resource.request = resource.request.replace(/^node:/, '');
},
),
new webpack.ProvidePlugin({
process: "process/browser", // provide a shim for the global `process` variable
process: 'process/browser', // provide a shim for the global `process` variable
}),
],
module: {

View File

@ -546,7 +546,7 @@ assert@^2.0.0:
asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==
available-typed-arrays@^1.0.5:
@ -554,10 +554,10 @@ available-typed-arrays@^1.0.5:
resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7"
integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==
axios@^1.3.4:
version "1.3.4"
resolved "https://registry.npmmirror.com/axios/-/axios-1.3.4.tgz#f5760cefd9cfb51fd2481acf88c05f67c4523024"
integrity sha512-toYm+Bsyl6VC5wSkfkbbNB6ROv7KY93PEBBL6xyDczaIHasAiv4wPqQ/c4RjoQzipxRD2W5g21cOqQulZ7rHwQ==
axios@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/axios/-/axios-1.4.0.tgz#38a7bf1224cd308de271146038b551d725f0be1f"
integrity sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==
dependencies:
follow-redirects "^1.15.0"
form-data "^4.0.0"
@ -657,7 +657,7 @@ buffer@^5.5.0:
call-bind@^1.0.0, call-bind@^1.0.2:
version "1.0.2"
resolved "https://registry.npmmirror.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c"
resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c"
integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==
dependencies:
function-bind "^1.1.1"
@ -799,7 +799,7 @@ colorette@^2.0.14:
combined-stream@^1.0.8:
version "1.0.8"
resolved "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
dependencies:
delayed-stream "~1.0.0"
@ -898,7 +898,7 @@ define-properties@^1.1.3:
delayed-stream@~1.0.0:
version "1.0.0"
resolved "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==
detect-libc@^2.0.0:
@ -1125,7 +1125,7 @@ esutils@^2.0.2:
resolved "https://registry.npmmirror.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
events@^3.2.0, events@^3.3.0:
events@^3.2.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400"
integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==
@ -1230,7 +1230,7 @@ flatted@^3.1.0:
follow-redirects@^1.15.0:
version "1.15.2"
resolved "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13"
integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==
for-each@^0.3.3:
@ -1242,7 +1242,7 @@ for-each@^0.3.3:
form-data@^4.0.0:
version "4.0.0"
resolved "https://registry.npmmirror.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452"
integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==
dependencies:
asynckit "^0.4.0"
@ -1283,7 +1283,7 @@ get-caller-file@^2.0.5:
resolved "https://registry.npmmirror.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3:
get-intrinsic@^1.0.2:
version "1.2.0"
resolved "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.2.0.tgz#7ad1dc0535f3a2904bba075772763e5051f6d05f"
integrity sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==
@ -1292,6 +1292,16 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3:
has "^1.0.3"
has-symbols "^1.0.3"
get-intrinsic@^1.1.1, get-intrinsic@^1.1.3:
version "1.2.1"
resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.1.tgz#d295644fed4505fc9cde952c37ee12b477a83d82"
integrity sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==
dependencies:
function-bind "^1.1.1"
has "^1.0.3"
has-proto "^1.0.1"
has-symbols "^1.0.3"
github-from-package@0.0.0:
version "0.0.0"
resolved "https://registry.npmmirror.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce"
@ -1416,6 +1426,11 @@ has-property-descriptors@^1.0.0:
dependencies:
get-intrinsic "^1.1.1"
has-proto@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0"
integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==
has-symbols@^1.0.2, has-symbols@^1.0.3:
version "1.0.3"
resolved "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8"
@ -1827,12 +1842,12 @@ micromatch@^4.0.0, micromatch@^4.0.4:
mime-db@1.52.0:
version "1.52.0"
resolved "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70"
integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
mime-types@^2.1.12, mime-types@^2.1.27:
version "2.1.35"
resolved "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a"
integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
dependencies:
mime-db "1.52.0"
@ -2171,7 +2186,7 @@ process@^0.11.10:
proxy-from-env@^1.1.0:
version "1.1.0"
resolved "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==
pump@^3.0.0:
@ -2490,6 +2505,12 @@ supports-preserve-symlinks-flag@^1.0.0:
resolved "https://registry.npmmirror.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
"tabby-agent@file:../tabby-agent":
version "0.0.1"
dependencies:
axios "^1.4.0"
form-data "^4.0.0"
tapable@^2.1.1, tapable@^2.2.0:
version "2.2.1"
resolved "https://registry.npmmirror.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0"