mirror of
https://github.com/ggerganov/llama.cpp.git
synced 2025-04-16 11:36:08 +00:00
Adding linenoise.cpp to llama-run (#11252)
This is a fork of linenoise that is C++17 compatible. I intend on adding it to llama-run so we can do things like traverse prompt history via the up and down arrows: https://github.com/ericcurtin/linenoise.cpp Signed-off-by: Eric Curtin <ecurtin@redhat.com>
This commit is contained in:
parent
4dd34ff831
commit
a1649cc13f
4
.github/workflows/build.yml
vendored
4
.github/workflows/build.yml
vendored
@ -87,6 +87,7 @@ jobs:
|
|||||||
if: ${{ ( github.event_name == 'push' && github.ref == 'refs/heads/master' ) || github.event.inputs.create_release == 'true' }}
|
if: ${{ ( github.event_name == 'push' && github.ref == 'refs/heads/master' ) || github.event.inputs.create_release == 'true' }}
|
||||||
run: |
|
run: |
|
||||||
cp LICENSE ./build/bin/
|
cp LICENSE ./build/bin/
|
||||||
|
cp examples/run/linenoise.cpp/LICENSE ./build/bin/LICENSE.linenoise.cpp
|
||||||
zip -r llama-${{ steps.tag.outputs.name }}-bin-macos-arm64.zip ./build/bin/*
|
zip -r llama-${{ steps.tag.outputs.name }}-bin-macos-arm64.zip ./build/bin/*
|
||||||
|
|
||||||
- name: Upload artifacts
|
- name: Upload artifacts
|
||||||
@ -149,6 +150,7 @@ jobs:
|
|||||||
if: ${{ ( github.event_name == 'push' && github.ref == 'refs/heads/master' ) || github.event.inputs.create_release == 'true' }}
|
if: ${{ ( github.event_name == 'push' && github.ref == 'refs/heads/master' ) || github.event.inputs.create_release == 'true' }}
|
||||||
run: |
|
run: |
|
||||||
cp LICENSE ./build/bin/
|
cp LICENSE ./build/bin/
|
||||||
|
cp examples/run/linenoise.cpp/LICENSE ./build/bin/LICENSE.linenoise.cpp
|
||||||
zip -r llama-${{ steps.tag.outputs.name }}-bin-macos-x64.zip ./build/bin/*
|
zip -r llama-${{ steps.tag.outputs.name }}-bin-macos-x64.zip ./build/bin/*
|
||||||
|
|
||||||
- name: Upload artifacts
|
- name: Upload artifacts
|
||||||
@ -217,6 +219,7 @@ jobs:
|
|||||||
if: ${{ ( github.event_name == 'push' && github.ref == 'refs/heads/master' ) || github.event.inputs.create_release == 'true' }}
|
if: ${{ ( github.event_name == 'push' && github.ref == 'refs/heads/master' ) || github.event.inputs.create_release == 'true' }}
|
||||||
run: |
|
run: |
|
||||||
cp LICENSE ./build/bin/
|
cp LICENSE ./build/bin/
|
||||||
|
cp examples/run/linenoise.cpp/LICENSE ./build/bin/LICENSE.linenoise.cpp
|
||||||
zip -r llama-${{ steps.tag.outputs.name }}-bin-ubuntu-x64.zip ./build/bin/*
|
zip -r llama-${{ steps.tag.outputs.name }}-bin-ubuntu-x64.zip ./build/bin/*
|
||||||
|
|
||||||
- name: Upload artifacts
|
- name: Upload artifacts
|
||||||
@ -796,6 +799,7 @@ jobs:
|
|||||||
if: ${{ ( github.event_name == 'push' && github.ref == 'refs/heads/master' ) || github.event.inputs.create_release == 'true' }}
|
if: ${{ ( github.event_name == 'push' && github.ref == 'refs/heads/master' ) || github.event.inputs.create_release == 'true' }}
|
||||||
run: |
|
run: |
|
||||||
Copy-Item LICENSE .\build\bin\Release\llama.cpp.txt
|
Copy-Item LICENSE .\build\bin\Release\llama.cpp.txt
|
||||||
|
Copy-Item .\examples\run\linenoise.cpp\LICENSE .\build\bin\Release\linenoise.cpp.txt
|
||||||
7z a llama-${{ steps.tag.outputs.name }}-bin-win-${{ matrix.build }}.zip .\build\bin\Release\*
|
7z a llama-${{ steps.tag.outputs.name }}-bin-win-${{ matrix.build }}.zip .\build\bin\Release\*
|
||||||
|
|
||||||
- name: Upload artifacts
|
- name: Upload artifacts
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
set(TARGET llama-run)
|
set(TARGET llama-run)
|
||||||
add_executable(${TARGET} run.cpp)
|
add_executable(${TARGET} run.cpp linenoise.cpp/linenoise.cpp)
|
||||||
install(TARGETS ${TARGET} RUNTIME)
|
install(TARGETS ${TARGET} RUNTIME)
|
||||||
target_link_libraries(${TARGET} PRIVATE common llama ${CMAKE_THREAD_LIBS_INIT})
|
target_link_libraries(${TARGET} PRIVATE common llama ${CMAKE_THREAD_LIBS_INIT})
|
||||||
target_compile_features(${TARGET} PRIVATE cxx_std_17)
|
target_compile_features(${TARGET} PRIVATE cxx_std_17)
|
||||||
|
26
examples/run/linenoise.cpp/LICENSE
Normal file
26
examples/run/linenoise.cpp/LICENSE
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
Copyright (c) 2010-2014, Salvatore Sanfilippo <antirez at gmail dot com>
|
||||||
|
Copyright (c) 2010-2013, Pieter Noordhuis <pcnoordhuis at gmail dot com>
|
||||||
|
Copyright (c) 2025, Eric Curtin <ericcurtin17 at gmail dot com>
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
1351
examples/run/linenoise.cpp/linenoise.cpp
Normal file
1351
examples/run/linenoise.cpp/linenoise.cpp
Normal file
File diff suppressed because it is too large
Load Diff
114
examples/run/linenoise.cpp/linenoise.h
Normal file
114
examples/run/linenoise.cpp/linenoise.h
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
/* linenoise.h -- VERSION 1.0
|
||||||
|
*
|
||||||
|
* Guerrilla line editing library against the idea that a line editing lib
|
||||||
|
* needs to be 20,000 lines of C++ code.
|
||||||
|
*
|
||||||
|
* See linenoise.cpp for more information.
|
||||||
|
*
|
||||||
|
* ------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010-2023, Salvatore Sanfilippo <antirez at gmail dot com>
|
||||||
|
* Copyright (c) 2010-2013, Pieter Noordhuis <pcnoordhuis at gmail dot com>
|
||||||
|
* Copyright (c) 2025, Eric Curtin <ericcurtin17 at gmail dot com>
|
||||||
|
*
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __LINENOISE_H
|
||||||
|
#define __LINENOISE_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stddef.h> /* For size_t. */
|
||||||
|
|
||||||
|
extern const char *linenoiseEditMore;
|
||||||
|
|
||||||
|
/* The linenoiseState structure represents the state during line editing.
|
||||||
|
* We pass this state to functions implementing specific editing
|
||||||
|
* functionalities. */
|
||||||
|
struct linenoiseState {
|
||||||
|
int in_completion; /* The user pressed TAB and we are now in completion
|
||||||
|
* mode, so input is handled by completeLine(). */
|
||||||
|
size_t completion_idx; /* Index of next completion to propose. */
|
||||||
|
int ifd; /* Terminal stdin file descriptor. */
|
||||||
|
int ofd; /* Terminal stdout file descriptor. */
|
||||||
|
char *buf; /* Edited line buffer. */
|
||||||
|
size_t buflen; /* Edited line buffer size. */
|
||||||
|
const char *prompt; /* Prompt to display. */
|
||||||
|
size_t plen; /* Prompt length. */
|
||||||
|
size_t pos; /* Current cursor position. */
|
||||||
|
size_t oldpos; /* Previous refresh cursor position. */
|
||||||
|
size_t len; /* Current edited line length. */
|
||||||
|
size_t cols; /* Number of columns in terminal. */
|
||||||
|
size_t oldrows; /* Rows used by last refrehsed line (multiline mode) */
|
||||||
|
int history_index; /* The history index we are currently editing. */
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct linenoiseCompletions {
|
||||||
|
size_t len;
|
||||||
|
char **cvec;
|
||||||
|
} linenoiseCompletions;
|
||||||
|
|
||||||
|
/* Non blocking API. */
|
||||||
|
int linenoiseEditStart(struct linenoiseState *l, int stdin_fd, int stdout_fd, char *buf, size_t buflen, const char *prompt);
|
||||||
|
const char *linenoiseEditFeed(struct linenoiseState *l);
|
||||||
|
void linenoiseEditStop(struct linenoiseState *l);
|
||||||
|
void linenoiseHide(struct linenoiseState *l);
|
||||||
|
void linenoiseShow(struct linenoiseState *l);
|
||||||
|
|
||||||
|
/* Blocking API. */
|
||||||
|
const char *linenoise(const char *prompt);
|
||||||
|
void linenoiseFree(void *ptr);
|
||||||
|
|
||||||
|
/* Completion API. */
|
||||||
|
typedef void(linenoiseCompletionCallback)(const char *, linenoiseCompletions *);
|
||||||
|
typedef const char*(linenoiseHintsCallback)(const char *, int *color, int *bold);
|
||||||
|
typedef void(linenoiseFreeHintsCallback)(const char *);
|
||||||
|
void linenoiseSetCompletionCallback(linenoiseCompletionCallback *);
|
||||||
|
void linenoiseSetHintsCallback(linenoiseHintsCallback *);
|
||||||
|
void linenoiseSetFreeHintsCallback(linenoiseFreeHintsCallback *);
|
||||||
|
void linenoiseAddCompletion(linenoiseCompletions *, const char *);
|
||||||
|
|
||||||
|
/* History API. */
|
||||||
|
int linenoiseHistoryAdd(const char *line);
|
||||||
|
int linenoiseHistorySetMaxLen(int len);
|
||||||
|
int linenoiseHistorySave(const char *filename);
|
||||||
|
int linenoiseHistoryLoad(const char *filename);
|
||||||
|
|
||||||
|
/* Other utilities. */
|
||||||
|
void linenoiseClearScreen(void);
|
||||||
|
void linenoiseSetMultiLine(int ml);
|
||||||
|
void linenoisePrintKeyCodes(void);
|
||||||
|
void linenoiseMaskModeEnable(void);
|
||||||
|
void linenoiseMaskModeDisable(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __LINENOISE_H */
|
@ -19,12 +19,14 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <list>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "json.hpp"
|
#include "json.hpp"
|
||||||
|
#include "linenoise.cpp/linenoise.h"
|
||||||
#include "llama-cpp.h"
|
#include "llama-cpp.h"
|
||||||
|
|
||||||
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) || defined(_WIN32)
|
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) || defined(_WIN32)
|
||||||
@ -536,7 +538,7 @@ class LlamaData {
|
|||||||
llama_sampler_ptr sampler;
|
llama_sampler_ptr sampler;
|
||||||
llama_context_ptr context;
|
llama_context_ptr context;
|
||||||
std::vector<llama_chat_message> messages;
|
std::vector<llama_chat_message> messages;
|
||||||
std::vector<std::string> msg_strs;
|
std::list<std::string> msg_strs;
|
||||||
std::vector<char> fmtted;
|
std::vector<char> fmtted;
|
||||||
|
|
||||||
int init(Opt & opt) {
|
int init(Opt & opt) {
|
||||||
@ -807,24 +809,44 @@ static int generate(LlamaData & llama_data, const std::string & prompt, std::str
|
|||||||
batch = llama_batch_get_one(&new_token_id, 1);
|
batch = llama_batch_get_one(&new_token_id, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("\033[0m");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int read_user_input(std::string & user) {
|
static int read_user_input(std::string & user_input) {
|
||||||
std::getline(std::cin, user);
|
static const char * prompt_prefix = "> ";
|
||||||
|
#ifdef WIN32
|
||||||
|
printf(
|
||||||
|
"\r%*s"
|
||||||
|
"\r\033[0m%s",
|
||||||
|
get_terminal_width(), " ", prompt_prefix);
|
||||||
|
|
||||||
|
std::getline(std::cin, user_input);
|
||||||
if (std::cin.eof()) {
|
if (std::cin.eof()) {
|
||||||
printf("\n");
|
printf("\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
if (user == "/bye") {
|
std::unique_ptr<char, decltype(&std::free)> line(const_cast<char *>(linenoise(prompt_prefix)), free);
|
||||||
|
if (!line) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user.empty()) {
|
user_input = line.get();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (user_input == "/bye") {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (user_input.empty()) {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef WIN32
|
||||||
|
linenoiseHistoryAdd(line.get());
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0; // Should have data in happy path
|
return 0; // Should have data in happy path
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -865,10 +887,6 @@ static int handle_user_input(std::string & user_input, const std::string & user)
|
|||||||
return 0; // No need for interactive input
|
return 0; // No need for interactive input
|
||||||
}
|
}
|
||||||
|
|
||||||
printf(
|
|
||||||
"\r%*s"
|
|
||||||
"\r\033[32m> \033[0m",
|
|
||||||
get_terminal_width(), " ");
|
|
||||||
return read_user_input(user_input); // Returns true if input ends the loop
|
return read_user_input(user_input); // Returns true if input ends the loop
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user