Code Monkey home page Code Monkey logo

chatgpt-tui's Introduction

ChatGPT-TUI

A terminal user interface for ChatGPT with an empasis on importing/exporting code (no more copy/pasting!).

Should work for Node.js 14.15.0 and above.

basic usage

Features:

  • ๐Ÿ–จ๏ธ Export code blocks to files or copy to clipboard
  • ๐Ÿ’พ Load code from files and insert into the conversation
  • ๐ŸŒŽ Load content from websites (i.e. documentation) and insert into the conversation
  • โœ’๏ธ Syntax highlighting for code blocks

Why not just use GitHub Copilot?

You should! But one missing feature is the ability to iterate on a solution. For non-trivial problems, its unlikely that the first solution it comes up with is correct. Having the model "think step by step" can dramatically improve its abilities on complex tasks. With ChatGPT-TUI, you can iterate on your solution and export it to a file (without all the copy/pasting).

Quick Start

To install and run, simply type the following into your terminal:

npx chatgpt-tui

If this is your first time running the program, it will prompt you for your OpenAI API key. After you've created an OpenAI account, you can get one here.

From there, you can start chatting with ChatGPT, much like you would with the ChatGPT website.

Loading Local Files

You can load local files into the conversation by using the $FILE(<path>) syntax. For example, if you wanted to load the contents of ./src/index.ts into the conversation, you would do:

The contents of ./src/index.ts are: \n\n $FILE(./src/index.ts)

loading a local file

To load specific lines of a file (as opposed to the entire thing), add brackets after the path but before the closing parenthesis. For example, to load lines 1-5 of ./src/index.ts, you would do:

This will load the first 5 lines of ./src/index.ts \n\n $FILE(./src/index.ts[1:5])

To load an entire directory, you can use the $FOLDER(<path>) syntax. Note, this is not reccomended because you will likely exceed the token limit.

Loading Content from Websites (experimental!)

You can load content from websites into the conversation by using the $URL(<url>) syntax. For example, if you wanted to load the contents of the OpenAI documentation into the conversation, you would do:

loading a website

This feature is still a work in progress, bugs are expected.

CLI Options

--user-msg

Preload the first message you type. When combined with some bash scripting, this can be used to automate the refactoring of multiple files, especially when the refactoring is non-trivial (i.e. hard to solve with a simple codegen)

For instance, to convert all the files in ./src to use ES6 modules, you could do:

for file in ./src/\*; do
  npx chatgpt-tui --user-msg "Refactor this code to use ES6 modules $file \n\n \$FILE($file)"
done

Notice we had to escape the second $ character in the user message. This is because bash will try to perform variable substitution, which we don't want, because we want it to be interpreted by ChatGPT-TUI.

--model

By default, we use the "gpt-3.5-turbo-0301" model. If you have access to the GPT4 models, you will greatly benefit from using those models.

--debug

Prints out the user message post transformations (i.e. after $FILE substitutions are made).

Future Features

I hacked this together in a few days, so it's not very polished. Here are some features I plan to add:

Support exporting multiple code blocks

Currently, the user has to select each code block individually to write to a file. I'd like to add a feature to export all code blocks at once.

Add CLI options

--log-dir

Should log the entire conversation to a directory.

chatgpt-tui's People

Contributors

narinluangrath avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

chatgpt-tui's Issues

An error occurred while calling OpenAI API Error: Request failed with status code 429

On first run with npx chaptgpt-tui

prompted to enter api key, I generated a new one from the openAI website and entered it.

I revoked the API key so this output doesn't contain any privileged info

Output was the following:

An error occurred while calling OpenAI API Error: Request failed with status code 429
    at createError (/Users/pierre/.npm/_npx/35e49236b7d89f21/node_modules/axios/lib/core/createError.js:16:15)
    at settle (/Users/pierre/.npm/_npx/35e49236b7d89f21/node_modules/axios/lib/core/settle.js:17:12)
    at RedirectableRequest.handleResponse (/Users/pierre/.npm/_npx/35e49236b7d89f21/node_modules/axios/lib/adapters/http.js:278:9)
    at RedirectableRequest.emit (node:events:511:28)
    at RedirectableRequest._processResponse (/Users/pierre/.npm/_npx/35e49236b7d89f21/node_modules/follow-redirects/index.js:356:10)
    at RedirectableRequest._onNativeResponse (/Users/pierre/.npm/_npx/35e49236b7d89f21/node_modules/follow-redirects/index.js:62:10)
    at Object.onceWrapper (node:events:626:26)
    at ClientRequest.emit (node:events:511:28)
    at HTTPParser.parserOnIncomingClient (node:_http_client:693:27)
    at HTTPParser.parserOnHeadersComplete (node:_http_common:119:17) {
  config: {
    transitional: {
      silentJSONParsing: true,
      forcedJSONParsing: true,
      clarifyTimeoutError: false
    },
    adapter: [Function: httpAdapter],
    transformRequest: [ [Function: transformRequest] ],
    transformResponse: [ [Function: transformResponse] ],
    timeout: 0,
    xsrfCookieName: 'XSRF-TOKEN',
    xsrfHeaderName: 'X-XSRF-TOKEN',
    maxContentLength: -1,
    maxBodyLength: -1,
    validateStatus: [Function: validateStatus],
    headers: {
      Accept: 'application/json, text/plain, */*',
      'Content-Type': 'application/json',
      'User-Agent': 'OpenAI/NodeJS/3.3.0',
      Authorization: 'Bearer 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',
      'Content-Length': 358
    },
    method: 'post',
    responseType: 'stream',
    data: '{"model":"gpt-3.5-turbo-0301","messages":[{"role":"system","content":"You are a helpful assistant whose main job is to write code. If you include code blocks in your responses, always include the language name after the opening triple backticks. For example, ```javascript\\nconsole.log(\'Hello, world!\');```"},{"role":"user","content":"hello"}],"stream":true}',
    url: 'https://api.openai.com/v1/chat/completions'
  },
  request: <ref *1> ClientRequest {
    _events: [Object: null prototype] {
      abort: [Function (anonymous)],
      aborted: [Function (anonymous)],
      connect: [Function (anonymous)],
      error: [Function (anonymous)],
      socket: [Function (anonymous)],
      timeout: [Function (anonymous)],
      finish: [Function: requestOnFinish]
    },
    _eventsCount: 7,
    _maxListeners: undefined,
    outputData: [],
    outputSize: 0,
    writable: true,
    destroyed: false,
    _last: false,
    chunkedEncoding: false,
    shouldKeepAlive: true,
    maxRequestsOnConnectionReached: false,
    _defaultKeepAlive: true,
    useChunkedEncodingByDefault: true,
    sendDate: false,
    _removedConnection: false,
    _removedContLen: false,
    _removedTE: false,
    strictContentLength: false,
    _contentLength: 358,
    _hasBody: true,
    _trailer: '',
    finished: true,
    _headerSent: true,
    _closed: false,
    socket: TLSSocket {
      _tlsOptions: [Object],
      _secureEstablished: true,
      _securePending: false,
      _newSessionPending: false,
      _controlReleased: true,
      secureConnecting: false,
      _SNICallback: null,
      servername: 'api.openai.com',
      alpnProtocol: false,
      authorized: true,
      authorizationError: null,
      encrypted: true,
      _events: [Object: null prototype],
      _eventsCount: 9,
      connecting: false,
      _hadError: false,
      _parent: null,
      _host: 'api.openai.com',
      _closeAfterHandlingError: false,
      _readableState: [ReadableState],
      _maxListeners: undefined,
      _writableState: [WritableState],
      allowHalfOpen: false,
      _sockname: null,
      _pendingData: null,
      _pendingEncoding: '',
      server: undefined,
      _server: null,
      ssl: [TLSWrap],
      _requestCert: true,
      _rejectUnauthorized: true,
      timeout: 5000,
      parser: null,
      _httpMessage: [Circular *1],
      autoSelectFamilyAttemptedAddresses: [Array],
      [Symbol(res)]: [TLSWrap],
      [Symbol(verified)]: true,
      [Symbol(pendingSession)]: null,
      [Symbol(async_id_symbol)]: 36,
      [Symbol(kHandle)]: [TLSWrap],
      [Symbol(lastWriteQueueSize)]: 0,
      [Symbol(timeout)]: Timeout {
        _idleTimeout: 5000,
        _idlePrev: [TimersList],
        _idleNext: [TimersList],
        _idleStart: 50071,
        _onTimeout: [Function: bound ],
        _timerArgs: undefined,
        _repeat: null,
        _destroyed: false,
        [Symbol(refed)]: false,
        [Symbol(kHasPrimitive)]: false,
        [Symbol(asyncId)]: 38,
        [Symbol(triggerId)]: 0
      },
      [Symbol(kBuffer)]: null,
      [Symbol(kBufferCb)]: null,
      [Symbol(kBufferGen)]: null,
      [Symbol(kCapture)]: false,
      [Symbol(kSetNoDelay)]: false,
      [Symbol(kSetKeepAlive)]: true,
      [Symbol(kSetKeepAliveInitialDelay)]: 60,
      [Symbol(kBytesRead)]: 0,
      [Symbol(kBytesWritten)]: 0,
      [Symbol(connect-options)]: [Object]
    },
    _header: 'POST /v1/chat/completions HTTP/1.1\r\n' +
      'Accept: application/json, text/plain, */*\r\n' +
      'Content-Type: application/json\r\n' +
      'User-Agent: OpenAI/NodeJS/3.3.0\r\n' +
      'Authorization: Bearer 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\r\n' +
      'Content-Length: 358\r\n' +
      'Host: api.openai.com\r\n' +
      'Connection: keep-alive\r\n' +
      '\r\n',
    _keepAliveTimeout: 0,
    _onPendingData: [Function: nop],
    agent: Agent {
      _events: [Object: null prototype],
      _eventsCount: 2,
      _maxListeners: undefined,
      defaultPort: 443,
      protocol: 'https:',
      options: [Object: null prototype],
      requests: [Object: null prototype] {},
      sockets: [Object: null prototype],
      freeSockets: [Object: null prototype] {},
      keepAliveMsecs: 1000,
      keepAlive: true,
      maxSockets: Infinity,
      maxFreeSockets: 256,
      scheduling: 'lifo',
      maxTotalSockets: Infinity,
      totalSocketCount: 1,
      maxCachedSessions: 100,
      _sessionCache: [Object],
      [Symbol(kCapture)]: false
    },
    socketPath: undefined,
    method: 'POST',
    maxHeaderSize: undefined,
    insecureHTTPParser: undefined,
    joinDuplicateHeaders: undefined,
    path: '/v1/chat/completions',
    _ended: false,
    res: IncomingMessage {
      _readableState: [ReadableState],
      _events: [Object: null prototype],
      _eventsCount: 1,
      _maxListeners: undefined,
      socket: [TLSSocket],
      httpVersionMajor: 1,
      httpVersionMinor: 1,
      httpVersion: '1.1',
      complete: true,
      rawHeaders: [Array],
      rawTrailers: [],
      joinDuplicateHeaders: undefined,
      aborted: false,
      upgrade: false,
      url: '',
      method: null,
      statusCode: 429,
      statusMessage: 'Too Many Requests',
      client: [TLSSocket],
      _consuming: false,
      _dumped: false,
      req: [Circular *1],
      responseUrl: 'https://api.openai.com/v1/chat/completions',
      redirects: [],
      [Symbol(kCapture)]: false,
      [Symbol(kHeaders)]: [Object],
      [Symbol(kHeadersCount)]: 22,
      [Symbol(kTrailers)]: null,
      [Symbol(kTrailersCount)]: 0
    },
    aborted: false,
    timeoutCb: [Function: emitRequestTimeout],
    upgradeOrConnect: false,
    parser: null,
    maxHeadersCount: null,
    reusedSocket: false,
    host: 'api.openai.com',
    protocol: 'https:',
    _redirectable: Writable {
      _writableState: [WritableState],
      _events: [Object: null prototype],
      _eventsCount: 3,
      _maxListeners: undefined,
      _options: [Object],
      _ended: true,
      _ending: true,
      _redirectCount: 0,
      _redirects: [],
      _requestBodyLength: 358,
      _requestBodyBuffers: [],
      _onNativeResponse: [Function (anonymous)],
      _currentRequest: [Circular *1],
      _currentUrl: 'https://api.openai.com/v1/chat/completions',
      [Symbol(kCapture)]: false
    },
    [Symbol(kCapture)]: false,
    [Symbol(kBytesWritten)]: 0,
    [Symbol(kNeedDrain)]: false,
    [Symbol(corked)]: 0,
    [Symbol(kOutHeaders)]: [Object: null prototype] {
      accept: [Array],
      'content-type': [Array],
      'user-agent': [Array],
      authorization: [Array],
      'content-length': [Array],
      host: [Array]
    },
    [Symbol(errored)]: null,
    [Symbol(kHighWaterMark)]: 16384,
    [Symbol(kRejectNonStandardBodyWrites)]: false,
    [Symbol(kUniqueHeaders)]: null
  },
  response: {
    status: 429,
    statusText: 'Too Many Requests',
    headers: {
      date: 'Fri, 21 Jul 2023 16:33:48 GMT',
      'content-type': 'application/json; charset=utf-8',
      'content-length': '222',
      connection: 'keep-alive',
      vary: 'Origin',
      'x-request-id': '137205a2e8e9908671b4af8d416486ae',
      'strict-transport-security': 'max-age=15724800; includeSubDomains',
      'cf-cache-status': 'DYNAMIC',
      server: 'cloudflare',
      'cf-ray': '7ea4d908495a15ac-SJC',
      'alt-svc': 'h3=":443"; ma=86400'
    },
    config: {
      transitional: [Object],
      adapter: [Function: httpAdapter],
      transformRequest: [Array],
      transformResponse: [Array],
      timeout: 0,
      xsrfCookieName: 'XSRF-TOKEN',
      xsrfHeaderName: 'X-XSRF-TOKEN',
      maxContentLength: -1,
      maxBodyLength: -1,
      validateStatus: [Function: validateStatus],
      headers: [Object],
      method: 'post',
      responseType: 'stream',
      data: '{"model":"gpt-3.5-turbo-0301","messages":[{"role":"system","content":"You are a helpful assistant whose main job is to write code. If you include code blocks in your responses, always include the language name after the opening triple backticks. For example, ```javascript\\nconsole.log(\'Hello, world!\');```"},{"role":"user","content":"hello"}],"stream":true}',
      url: 'https://api.openai.com/v1/chat/completions'
    },
    request: <ref *1> ClientRequest {
      _events: [Object: null prototype],
      _eventsCount: 7,
      _maxListeners: undefined,
      outputData: [],
      outputSize: 0,
      writable: true,
      destroyed: false,
      _last: false,
      chunkedEncoding: false,
      shouldKeepAlive: true,
      maxRequestsOnConnectionReached: false,
      _defaultKeepAlive: true,
      useChunkedEncodingByDefault: true,
      sendDate: false,
      _removedConnection: false,
      _removedContLen: false,
      _removedTE: false,
      strictContentLength: false,
      _contentLength: 358,
      _hasBody: true,
      _trailer: '',
      finished: true,
      _headerSent: true,
      _closed: false,
      socket: [TLSSocket],
      _header: 'POST /v1/chat/completions HTTP/1.1\r\n' +
        'Accept: application/json, text/plain, */*\r\n' +
        'Content-Type: application/json\r\n' +
        'User-Agent: OpenAI/NodeJS/3.3.0\r\n' +
        'Authorization: Bearer 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\r\n' +
        'Content-Length: 358\r\n' +
        'Host: api.openai.com\r\n' +
        'Connection: keep-alive\r\n' +
        '\r\n',
      _keepAliveTimeout: 0,
      _onPendingData: [Function: nop],
      agent: [Agent],
      socketPath: undefined,
      method: 'POST',
      maxHeaderSize: undefined,
      insecureHTTPParser: undefined,
      joinDuplicateHeaders: undefined,
      path: '/v1/chat/completions',
      _ended: false,
      res: [IncomingMessage],
      aborted: false,
      timeoutCb: [Function: emitRequestTimeout],
      upgradeOrConnect: false,
      parser: null,
      maxHeadersCount: null,
      reusedSocket: false,
      host: 'api.openai.com',
      protocol: 'https:',
      _redirectable: [Writable],
      [Symbol(kCapture)]: false,
      [Symbol(kBytesWritten)]: 0,
      [Symbol(kNeedDrain)]: false,
      [Symbol(corked)]: 0,
      [Symbol(kOutHeaders)]: [Object: null prototype],
      [Symbol(errored)]: null,
      [Symbol(kHighWaterMark)]: 16384,
      [Symbol(kRejectNonStandardBodyWrites)]: false,
      [Symbol(kUniqueHeaders)]: null
    },
    data: IncomingMessage {
      _readableState: [ReadableState],
      _events: [Object: null prototype],
      _eventsCount: 1,
      _maxListeners: undefined,
      socket: [TLSSocket],
      httpVersionMajor: 1,
      httpVersionMinor: 1,
      httpVersion: '1.1',
      complete: true,
      rawHeaders: [Array],
      rawTrailers: [],
      joinDuplicateHeaders: undefined,
      aborted: false,
      upgrade: false,
      url: '',
      method: null,
      statusCode: 429,
      statusMessage: 'Too Many Requests',
      client: [TLSSocket],
      _consuming: false,
      _dumped: false,
      req: [ClientRequest],
      responseUrl: 'https://api.openai.com/v1/chat/completions',
      redirects: [],
      [Symbol(kCapture)]: false,
      [Symbol(kHeaders)]: [Object],
      [Symbol(kHeadersCount)]: 22,
      [Symbol(kTrailers)]: null,
      [Symbol(kTrailersCount)]: 0
    }
  },
  isAxiosError: true,
  toJSON: [Function: toJSON]
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.