[chatgpt] Initial contribution of the ChatGPT binding (#14809)
* Initial contribution of the ChatGPT binding Signed-off-by: Kai Kreuzer <kai@openhab.org>
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<features name="org.openhab.binding.chatgpt-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.4.0">
|
||||
<repository>mvn:org.openhab.core.features.karaf/org.openhab.core.features.karaf.openhab-core/${ohc.version}/xml/features</repository>
|
||||
|
||||
<feature name="openhab-binding-chatgpt" description="ChatGPT Binding" version="${project.version}">
|
||||
<feature>openhab-runtime-base</feature>
|
||||
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.chatgpt/${project.version}</bundle>
|
||||
</feature>
|
||||
</features>
|
||||
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2023 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.chatgpt.internal;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
|
||||
/**
|
||||
* The {@link ChatGPTBindingConstants} class defines common constants, which are
|
||||
* used across the whole binding.
|
||||
*
|
||||
* @author Kai Kreuzer - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class ChatGPTBindingConstants {
|
||||
|
||||
private static final String BINDING_ID = "chatgpt";
|
||||
|
||||
// List of all Thing Type UIDs
|
||||
public static final ThingTypeUID THING_TYPE_ACCOUNT = new ThingTypeUID(BINDING_ID, "account");
|
||||
|
||||
// List of all Channel ids
|
||||
public static final String CHANNEL_CHAT = "chat";
|
||||
|
||||
public static final String OPENAI_API_URL = "https://api.openai.com/v1/chat/completions";
|
||||
public static final String OPENAI_MODELS_URL = "https://api.openai.com/v1/models";
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2023 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.chatgpt.internal;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* The {@link ChatGPTChannelConfiguration} class contains fields mapping chat channel configuration parameters.
|
||||
*
|
||||
* @author Kai Kreuzer - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class ChatGPTChannelConfiguration {
|
||||
|
||||
public String model = "";
|
||||
|
||||
public float temperature;
|
||||
|
||||
public String systemMessage = "";
|
||||
|
||||
int maxTokens;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2023 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.chatgpt.internal;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* The {@link ChatGPTConfiguration} class contains fields mapping thing configuration parameters.
|
||||
*
|
||||
* @author Kai Kreuzer - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class ChatGPTConfiguration {
|
||||
|
||||
public String apiKey = "";
|
||||
}
|
||||
@@ -0,0 +1,200 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2023 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.chatgpt.internal;
|
||||
|
||||
import static org.openhab.binding.chatgpt.internal.ChatGPTBindingConstants.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.client.api.ContentResponse;
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.client.util.StringContentProvider;
|
||||
import org.eclipse.jetty.http.HttpMethod;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.openhab.binding.chatgpt.internal.dto.ChatResponse;
|
||||
import org.openhab.core.io.net.http.HttpClientFactory;
|
||||
import org.openhab.core.library.types.StringType;
|
||||
import org.openhab.core.thing.Channel;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
import org.openhab.core.thing.binding.BaseThingHandler;
|
||||
import org.openhab.core.thing.binding.ThingHandlerService;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.openhab.core.types.RefreshType;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
/**
|
||||
* The {@link ChatGPTHandler} is responsible for handling commands, which are
|
||||
* sent to one of the channels.
|
||||
*
|
||||
* @author Kai Kreuzer - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class ChatGPTHandler extends BaseThingHandler {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(ChatGPTHandler.class);
|
||||
|
||||
private HttpClient httpClient;
|
||||
private Gson gson = new Gson();
|
||||
|
||||
private String apiKey = "";
|
||||
private String lastPrompt = "";
|
||||
|
||||
private List<String> models = List.of();
|
||||
|
||||
public ChatGPTHandler(Thing thing, HttpClientFactory httpClientFactory) {
|
||||
super(thing);
|
||||
this.httpClient = httpClientFactory.getCommonHttpClient();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
if (command instanceof RefreshType && !"".equals(lastPrompt)) {
|
||||
String response = sendPrompt(channelUID, lastPrompt);
|
||||
processChatResponse(channelUID, response);
|
||||
}
|
||||
|
||||
if (command instanceof StringType stringCommand) {
|
||||
lastPrompt = stringCommand.toFullString();
|
||||
String response = sendPrompt(channelUID, lastPrompt);
|
||||
processChatResponse(channelUID, response);
|
||||
}
|
||||
}
|
||||
|
||||
private void processChatResponse(ChannelUID channelUID, @Nullable String response) {
|
||||
if (response != null) {
|
||||
ChatResponse chatResponse = gson.fromJson(response, ChatResponse.class);
|
||||
if (chatResponse != null) {
|
||||
String msg = chatResponse.getChoices().get(0).getMessage().getContent();
|
||||
updateState(channelUID, new StringType(msg));
|
||||
} else {
|
||||
logger.warn("Didn't receive any response from ChatGPT - this is unexpected.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private @Nullable String sendPrompt(ChannelUID channelUID, String prompt) {
|
||||
Channel channel = getThing().getChannel(channelUID);
|
||||
if (channel == null) {
|
||||
logger.error("Channel with UID '{}' cannot be found on Thing '{}'.", channelUID, getThing().getUID());
|
||||
return null;
|
||||
}
|
||||
ChatGPTChannelConfiguration channelConfig = channel.getConfiguration().as(ChatGPTChannelConfiguration.class);
|
||||
|
||||
JsonObject root = new JsonObject();
|
||||
root.addProperty("temperature", channelConfig.temperature);
|
||||
root.addProperty("model", channelConfig.model);
|
||||
root.addProperty("max_tokens", channelConfig.maxTokens);
|
||||
|
||||
JsonObject systemMessage = new JsonObject();
|
||||
systemMessage.addProperty("role", "system");
|
||||
systemMessage.addProperty("content", channelConfig.systemMessage);
|
||||
JsonObject userMessage = new JsonObject();
|
||||
userMessage.addProperty("role", "user");
|
||||
userMessage.addProperty("content", prompt);
|
||||
JsonArray messages = new JsonArray(2);
|
||||
messages.add(systemMessage);
|
||||
messages.add(userMessage);
|
||||
root.add("messages", messages);
|
||||
|
||||
Request request = httpClient.newRequest(OPENAI_API_URL).method(HttpMethod.POST)
|
||||
.header("Content-Type", "application/json").header("Authorization", "Bearer " + apiKey)
|
||||
.content(new StringContentProvider(gson.toJson(root)));
|
||||
try {
|
||||
ContentResponse response = request.send();
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
if (response.getStatus() == HttpStatus.OK_200) {
|
||||
return response.getContentAsString();
|
||||
} else {
|
||||
logger.error("ChatGPT request resulted in HTTP {} with message: {}", response.getStatus(),
|
||||
response.getReason());
|
||||
return null;
|
||||
}
|
||||
} catch (InterruptedException | TimeoutException | ExecutionException e) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||
"Could not connect to OpenAI API: " + e.getMessage());
|
||||
logger.debug("Request to OpenAI failed: {}", e.getMessage(), e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
ChatGPTConfiguration config = getConfigAs(ChatGPTConfiguration.class);
|
||||
|
||||
String apiKey = config.apiKey;
|
||||
|
||||
if (apiKey.isBlank()) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
|
||||
"@text/offline.configuration-error");
|
||||
return;
|
||||
}
|
||||
|
||||
this.apiKey = apiKey;
|
||||
updateStatus(ThingStatus.UNKNOWN);
|
||||
|
||||
scheduler.execute(() -> {
|
||||
try {
|
||||
Request request = httpClient.newRequest(OPENAI_MODELS_URL).method(HttpMethod.GET)
|
||||
.header("Authorization", "Bearer " + apiKey);
|
||||
ContentResponse response = request.send();
|
||||
if (response.getStatus() == 200) {
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
JsonObject jsonObject = gson.fromJson(response.getContentAsString(), JsonObject.class);
|
||||
if (jsonObject != null) {
|
||||
JsonArray data = jsonObject.getAsJsonArray("data");
|
||||
|
||||
List<String> modelIds = new ArrayList<>();
|
||||
for (JsonElement element : data) {
|
||||
JsonObject model = element.getAsJsonObject();
|
||||
String id = model.get("id").getAsString();
|
||||
modelIds.add(id);
|
||||
}
|
||||
this.models = List.copyOf(modelIds);
|
||||
} else {
|
||||
logger.warn("Did not receive a valid JSON response from the models endpoint.");
|
||||
}
|
||||
} else {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||
"@text/offline.communication-error");
|
||||
}
|
||||
} catch (InterruptedException | ExecutionException | TimeoutException e) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
List<String> getModels() {
|
||||
return models;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Class<? extends ThingHandlerService>> getServices() {
|
||||
return List.of(ChatGPTModelOptionProvider.class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2023 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.chatgpt.internal;
|
||||
|
||||
import static org.openhab.binding.chatgpt.internal.ChatGPTBindingConstants.THING_TYPE_ACCOUNT;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.io.net.http.HttpClientFactory;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
import org.openhab.core.thing.binding.BaseThingHandlerFactory;
|
||||
import org.openhab.core.thing.binding.ThingHandler;
|
||||
import org.openhab.core.thing.binding.ThingHandlerFactory;
|
||||
import org.osgi.service.component.annotations.Activate;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.osgi.service.component.annotations.Reference;
|
||||
|
||||
/**
|
||||
* The {@link ChatGPTHandlerFactory} is responsible for creating things and thing
|
||||
* handlers.
|
||||
*
|
||||
* @author Kai Kreuzer - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
@Component(configurationPid = "binding.chatgpt", service = ThingHandlerFactory.class)
|
||||
public class ChatGPTHandlerFactory extends BaseThingHandlerFactory {
|
||||
|
||||
private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Set.of(THING_TYPE_ACCOUNT);
|
||||
private HttpClientFactory httpClientFactory;
|
||||
|
||||
@Activate
|
||||
public ChatGPTHandlerFactory(@Reference HttpClientFactory httpClientFactory) {
|
||||
this.httpClientFactory = httpClientFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
|
||||
return SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nullable ThingHandler createHandler(Thing thing) {
|
||||
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
|
||||
|
||||
if (THING_TYPE_ACCOUNT.equals(thingTypeUID)) {
|
||||
return new ChatGPTHandler(thing, httpClientFactory);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2023 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.chatgpt.internal;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.config.core.ConfigOptionProvider;
|
||||
import org.openhab.core.config.core.ParameterOption;
|
||||
import org.openhab.core.thing.binding.ThingHandler;
|
||||
import org.openhab.core.thing.binding.ThingHandlerService;
|
||||
|
||||
/**
|
||||
* The {@link ChatGPTModelOptionProvider} provides the available models from OpenAI as options for the channel
|
||||
* configuration.
|
||||
*
|
||||
* @author Kai Kreuzer - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class ChatGPTModelOptionProvider implements ThingHandlerService, ConfigOptionProvider {
|
||||
|
||||
private @Nullable ThingHandler thingHandler;
|
||||
|
||||
@Override
|
||||
public @Nullable Collection<ParameterOption> getParameterOptions(URI uri, String param, @Nullable String context,
|
||||
@Nullable Locale locale) {
|
||||
if ("model".equals(param)) {
|
||||
List<ParameterOption> options = new ArrayList<>();
|
||||
if (thingHandler instanceof ChatGPTHandler chatGPTHandler) {
|
||||
chatGPTHandler.getModels().forEach(model -> options.add(new ParameterOption(model, model)));
|
||||
}
|
||||
return options;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setThingHandler(ThingHandler handler) {
|
||||
this.thingHandler = handler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ThingHandler getThingHandler() {
|
||||
return thingHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void activate() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2023 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.chatgpt.internal.dto;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
/**
|
||||
* This is a dto used for parsing the JSON response from ChatGPT.
|
||||
*
|
||||
* @author Kai Kreuzer - Initial contribution
|
||||
*
|
||||
*/
|
||||
public class ChatResponse {
|
||||
|
||||
private List<Choice> choices;
|
||||
private String id;
|
||||
private String object;
|
||||
private int created;
|
||||
private String model;
|
||||
|
||||
public List<Choice> getChoices() {
|
||||
return choices;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public int getCreated() {
|
||||
return created;
|
||||
}
|
||||
|
||||
public String getObject() {
|
||||
return object;
|
||||
}
|
||||
|
||||
public String getModel() {
|
||||
return model;
|
||||
}
|
||||
|
||||
public static class Choice {
|
||||
private Message message;
|
||||
|
||||
@SerializedName("finish_reason")
|
||||
private String finishReason;
|
||||
private int index;
|
||||
|
||||
public Message getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public String getFinishReason() {
|
||||
return finishReason;
|
||||
}
|
||||
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Message {
|
||||
private String role;
|
||||
private String content;
|
||||
|
||||
public String getRole() {
|
||||
return role;
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<addon:addon id="chatgpt" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:addon="https://openhab.org/schemas/addon/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/addon/v1.0.0 https://openhab.org/schemas/addon-1.0.0.xsd">
|
||||
|
||||
<type>binding</type>
|
||||
<name>ChatGPT Binding</name>
|
||||
<description>This binding allows interaction with OpenAI's ChatGPT.</description>
|
||||
<connection>cloud</connection>
|
||||
|
||||
</addon:addon>
|
||||
@@ -0,0 +1,35 @@
|
||||
# add-on
|
||||
|
||||
addon.chatgpt.name = ChatGPT Binding
|
||||
addon.chatgpt.description = This binding allows interaction with OpenAI's ChatGPT.
|
||||
|
||||
# thing types
|
||||
|
||||
thing-type.chatgpt.account.label = OpenAI Account
|
||||
thing-type.chatgpt.account.description = Account at OpenAI that is used for accessing the ChatGPT API.
|
||||
|
||||
# thing types config
|
||||
|
||||
thing-type.config.chatgpt.account.apiKey.label = API Key
|
||||
thing-type.config.chatgpt.account.apiKey.description = API key to access the account
|
||||
|
||||
# channel types
|
||||
|
||||
channel-type.chatgpt.chat.label = Chat
|
||||
channel-type.chatgpt.chat.description = A chat session
|
||||
|
||||
# channel types config
|
||||
|
||||
channel-type.config.chatgpt.chat.maxTokens.label = Maximum Number of Tokens
|
||||
channel-type.config.chatgpt.chat.maxTokens.description = The maximum number of tokens to generate in the completion.
|
||||
channel-type.config.chatgpt.chat.model.label = Model
|
||||
channel-type.config.chatgpt.chat.model.description = The model to be used for the responses
|
||||
channel-type.config.chatgpt.chat.systemMessage.label = System Message
|
||||
channel-type.config.chatgpt.chat.systemMessage.description = The system message helps set the behavior of the assistant.
|
||||
channel-type.config.chatgpt.chat.temperature.label = Temperature
|
||||
channel-type.config.chatgpt.chat.temperature.description = Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic.
|
||||
|
||||
# Status messages
|
||||
|
||||
offline.configuration-error=No API key configured
|
||||
offline.communication-error=Could not connect to OpenAI API
|
||||
@@ -0,0 +1,55 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="chatgpt"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<thing-type id="account" extensible="chat">
|
||||
|
||||
<label>OpenAI Account</label>
|
||||
<description>Account at OpenAI that is used for accessing the ChatGPT API.</description>
|
||||
|
||||
<channels>
|
||||
<channel id="chat" typeId="chat"/>
|
||||
</channels>
|
||||
|
||||
<config-description>
|
||||
<parameter name="apiKey" type="text" required="true">
|
||||
<context>password</context>
|
||||
<label>API Key</label>
|
||||
<description>API key to access the account</description>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</thing-type>
|
||||
|
||||
<channel-type id="chat">
|
||||
<item-type>String</item-type>
|
||||
<label>Chat</label>
|
||||
<description>A chat session</description>
|
||||
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||
<config-description>
|
||||
<parameter name="model" type="text">
|
||||
<label>Model</label>
|
||||
<description>The model to be used for the responses</description>
|
||||
<limitToOptions>false</limitToOptions>
|
||||
<default>gpt-3.5-turbo</default>
|
||||
</parameter>
|
||||
<parameter name="temperature" type="decimal" min="0" max="2">
|
||||
<label>Temperature</label>
|
||||
<description>Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more
|
||||
focused and deterministic.</description>
|
||||
<default>0.5</default>
|
||||
</parameter>
|
||||
<parameter name="systemMessage" type="text">
|
||||
<label>System Message</label>
|
||||
<description>The system message helps set the behavior of the assistant.</description>
|
||||
</parameter>
|
||||
<parameter name="maxTokens" type="decimal">
|
||||
<label>Maximum Number of Tokens</label>
|
||||
<description>The maximum number of tokens to generate in the completion.</description>
|
||||
<default>500</default>
|
||||
<advanced>true</advanced>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</channel-type>
|
||||
</thing:thing-descriptions>
|
||||
Reference in New Issue
Block a user