first commit
This commit is contained in:
Vendored
+58
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* Most of this code is from Zotero team's official Make It Red example[1]
|
||||
* or the Zotero 7 documentation[2].
|
||||
* [1] https://github.com/zotero/make-it-red
|
||||
* [2] https://www.zotero.org/support/dev/zotero_7_for_developers
|
||||
*/
|
||||
|
||||
var chromeHandle;
|
||||
|
||||
function install(data, reason) {}
|
||||
|
||||
async function startup({ id, version, resourceURI, rootURI }, reason) {
|
||||
var aomStartup = Components.classes[
|
||||
"@mozilla.org/addons/addon-manager-startup;1"
|
||||
].getService(Components.interfaces.amIAddonManagerStartup);
|
||||
var manifestURI = Services.io.newURI(rootURI + "manifest.json");
|
||||
chromeHandle = aomStartup.registerChrome(manifestURI, [
|
||||
["content", "__addonRef__", rootURI + "content/"],
|
||||
]);
|
||||
|
||||
/**
|
||||
* Global variables for plugin code.
|
||||
* The `_globalThis` is the global root variable of the plugin sandbox environment
|
||||
* and all child variables assigned to it is globally accessible.
|
||||
* See `src/index.ts` for details.
|
||||
*/
|
||||
const ctx = { rootURI };
|
||||
ctx._globalThis = ctx;
|
||||
|
||||
Services.scriptloader.loadSubScript(
|
||||
`${rootURI}/content/scripts/__addonRef__.js`,
|
||||
ctx,
|
||||
);
|
||||
await Zotero.__addonInstance__.hooks.onStartup();
|
||||
}
|
||||
|
||||
async function onMainWindowLoad({ window }, reason) {
|
||||
await Zotero.__addonInstance__?.hooks.onMainWindowLoad(window);
|
||||
}
|
||||
|
||||
async function onMainWindowUnload({ window }, reason) {
|
||||
await Zotero.__addonInstance__?.hooks.onMainWindowUnload(window);
|
||||
}
|
||||
|
||||
async function shutdown({ id, version, resourceURI, rootURI }, reason) {
|
||||
if (reason === APP_SHUTDOWN) {
|
||||
return;
|
||||
}
|
||||
|
||||
await Zotero.__addonInstance__?.hooks.onShutdown();
|
||||
|
||||
if (chromeHandle) {
|
||||
chromeHandle.destruct();
|
||||
chromeHandle = null;
|
||||
}
|
||||
}
|
||||
|
||||
async function uninstall(data, reason) {}
|
||||
@@ -0,0 +1,140 @@
|
||||
.chatpapers-root {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
padding: 8px;
|
||||
min-height: 320px;
|
||||
box-sizing: border-box;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.chatpapers-header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
.chatpapers-title {
|
||||
font-weight: 600;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.chatpapers-meta {
|
||||
opacity: 0.7;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.chatpapers-messages {
|
||||
flex: 1;
|
||||
min-height: 180px;
|
||||
max-height: 420px;
|
||||
overflow: auto;
|
||||
border: 1px solid color-mix(in srgb, currentColor 18%, transparent);
|
||||
border-radius: 8px;
|
||||
padding: 8px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
background: color-mix(in srgb, currentColor 4%, transparent);
|
||||
}
|
||||
|
||||
.chatpapers-bubble {
|
||||
padding: 8px 10px;
|
||||
border-radius: 8px;
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.chatpapers-user {
|
||||
background: color-mix(in srgb, #3b82f6 18%, transparent);
|
||||
align-self: flex-end;
|
||||
max-width: 92%;
|
||||
}
|
||||
|
||||
.chatpapers-assistant {
|
||||
background: color-mix(in srgb, currentColor 8%, transparent);
|
||||
align-self: flex-start;
|
||||
max-width: 96%;
|
||||
}
|
||||
|
||||
.chatpapers-role {
|
||||
font-size: 11px;
|
||||
opacity: 0.65;
|
||||
margin-bottom: 4px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.chatpapers-status {
|
||||
min-height: 1.2em;
|
||||
font-size: 12px;
|
||||
opacity: 0.85;
|
||||
}
|
||||
|
||||
.chatpapers-status[data-kind="warn"] {
|
||||
color: #b45309;
|
||||
}
|
||||
|
||||
.chatpapers-status[data-kind="error"] {
|
||||
color: #b91c1c;
|
||||
}
|
||||
|
||||
.chatpapers-toolbar,
|
||||
.chatpapers-actions {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.chatpapers-btn {
|
||||
appearance: none;
|
||||
border: 1px solid color-mix(in srgb, currentColor 22%, transparent);
|
||||
background: color-mix(in srgb, currentColor 6%, transparent);
|
||||
border-radius: 6px;
|
||||
padding: 4px 10px;
|
||||
cursor: pointer;
|
||||
font: inherit;
|
||||
}
|
||||
|
||||
.chatpapers-btn:hover:not(:disabled) {
|
||||
background: color-mix(in srgb, currentColor 12%, transparent);
|
||||
}
|
||||
|
||||
.chatpapers-btn:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.chatpapers-primary {
|
||||
background: #2563eb;
|
||||
border-color: #2563eb;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.chatpapers-primary:hover:not(:disabled) {
|
||||
background: #1d4ed8;
|
||||
}
|
||||
|
||||
.chatpapers-input {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
resize: vertical;
|
||||
min-height: 64px;
|
||||
border-radius: 8px;
|
||||
border: 1px solid color-mix(in srgb, currentColor 22%, transparent);
|
||||
padding: 8px;
|
||||
font: inherit;
|
||||
background: transparent;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.chatpapers-loading {
|
||||
padding: 12px;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.chatpapers-pref-hint {
|
||||
opacity: 0.8;
|
||||
font-size: 12px;
|
||||
margin: 4px 0 10px;
|
||||
max-width: 52em;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" fill="context-fill" stroke="context-stroke">
|
||||
<path d="M3.5 4.5h13a1.5 1.5 0 0 1 1.5 1.5v7a1.5 1.5 0 0 1-1.5 1.5H8l-3.2 2.4a.5.5 0 0 1-.8-.4V14.5H3.5A1.5 1.5 0 0 1 2 13V6a1.5 1.5 0 0 1 1.5-1.5z"/>
|
||||
<circle cx="7" cy="9.5" r="1"/>
|
||||
<circle cx="10" cy="9.5" r="1"/>
|
||||
<circle cx="13" cy="9.5" r="1"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 392 B |
Binary file not shown.
|
After Width: | Height: | Size: 677 B |
Binary file not shown.
|
After Width: | Height: | Size: 836 B |
@@ -0,0 +1,127 @@
|
||||
<linkset>
|
||||
<html:link rel="localization" href="__addonRef__-preferences.ftl" />
|
||||
</linkset>
|
||||
<groupbox
|
||||
onload="Zotero.__addonInstance__.hooks.onPrefsEvent('load', { window })"
|
||||
>
|
||||
<label><html:h2 data-l10n-id="prefs-section-provider"></html:h2></label>
|
||||
<html:p id="chatpapers-pref-hint" class="chatpapers-pref-hint"></html:p>
|
||||
|
||||
<hbox align="center">
|
||||
<html:label
|
||||
for="chatpapers-pref-provider"
|
||||
data-l10n-id="prefs-provider"
|
||||
></html:label>
|
||||
<html:select id="chatpapers-pref-provider" preference="provider">
|
||||
</html:select>
|
||||
<button id="chatpapers-pref-reset" data-l10n-id="prefs-reset"></button>
|
||||
</hbox>
|
||||
|
||||
<hbox align="center">
|
||||
<html:label
|
||||
for="chatpapers-pref-apiBaseUrl"
|
||||
data-l10n-id="prefs-base-url"
|
||||
></html:label>
|
||||
<html:input
|
||||
type="text"
|
||||
id="chatpapers-pref-apiBaseUrl"
|
||||
preference="apiBaseUrl"
|
||||
></html:input>
|
||||
</hbox>
|
||||
|
||||
<hbox align="center">
|
||||
<html:label
|
||||
for="zotero-prefpane-__addonRef__-apiKey"
|
||||
data-l10n-id="prefs-api-key"
|
||||
></html:label>
|
||||
<html:input
|
||||
type="password"
|
||||
id="zotero-prefpane-__addonRef__-apiKey"
|
||||
preference="apiKey"
|
||||
></html:input>
|
||||
</hbox>
|
||||
|
||||
<hbox align="center">
|
||||
<html:label
|
||||
for="chatpapers-pref-model"
|
||||
data-l10n-id="prefs-model"
|
||||
></html:label>
|
||||
<html:input
|
||||
type="text"
|
||||
id="chatpapers-pref-model"
|
||||
preference="model"
|
||||
></html:input>
|
||||
<button
|
||||
id="chatpapers-pref-refresh-models"
|
||||
data-l10n-id="prefs-refresh-models"
|
||||
></button>
|
||||
</hbox>
|
||||
</groupbox>
|
||||
|
||||
<groupbox>
|
||||
<label><html:h2 data-l10n-id="prefs-section-generation"></html:h2></label>
|
||||
<hbox align="center">
|
||||
<html:label data-l10n-id="prefs-temperature"></html:label>
|
||||
<html:input
|
||||
type="text"
|
||||
preference="temperature"
|
||||
></html:input>
|
||||
</hbox>
|
||||
<hbox align="center">
|
||||
<html:label data-l10n-id="prefs-max-tokens"></html:label>
|
||||
<html:input
|
||||
type="number"
|
||||
preference="maxTokens"
|
||||
min="256"
|
||||
max="128000"
|
||||
></html:input>
|
||||
</hbox>
|
||||
<hbox align="center">
|
||||
<html:label data-l10n-id="prefs-timeout"></html:label>
|
||||
<html:input
|
||||
type="number"
|
||||
preference="timeoutMs"
|
||||
min="10000"
|
||||
step="1000"
|
||||
></html:input>
|
||||
</hbox>
|
||||
<hbox align="center">
|
||||
<html:label data-l10n-id="prefs-max-context"></html:label>
|
||||
<html:input
|
||||
type="number"
|
||||
preference="maxContextChars"
|
||||
min="5000"
|
||||
step="1000"
|
||||
></html:input>
|
||||
</hbox>
|
||||
<hbox align="center">
|
||||
<html:label data-l10n-id="prefs-answer-language"></html:label>
|
||||
<html:input type="text" preference="answerLanguage"></html:input>
|
||||
</hbox>
|
||||
<checkbox preference="sendMetadata" data-l10n-id="prefs-send-metadata" />
|
||||
</groupbox>
|
||||
|
||||
<groupbox>
|
||||
<label><html:h2 data-l10n-id="prefs-section-openrouter"></html:h2></label>
|
||||
<hbox align="center">
|
||||
<html:label data-l10n-id="prefs-openrouter-referer"></html:label>
|
||||
<html:input
|
||||
type="text"
|
||||
preference="openrouterReferer"
|
||||
></html:input>
|
||||
</hbox>
|
||||
<hbox align="center">
|
||||
<html:label data-l10n-id="prefs-openrouter-title"></html:label>
|
||||
<html:input type="text" preference="openrouterTitle"></html:input>
|
||||
</hbox>
|
||||
</groupbox>
|
||||
|
||||
<groupbox>
|
||||
<label><html:h2 data-l10n-id="prefs-section-prompts"></html:h2></label>
|
||||
<html:label data-l10n-id="prefs-system-prompt"></html:label>
|
||||
<html:textarea preference="systemPrompt" rows="4"></html:textarea>
|
||||
<html:label data-l10n-id="prefs-summary-prompt"></html:label>
|
||||
<html:textarea preference="summaryPrompt" rows="4"></html:textarea>
|
||||
</groupbox>
|
||||
|
||||
<html:p data-l10n-id="prefs-privacy" class="chatpapers-pref-hint"></html:p>
|
||||
@@ -0,0 +1,3 @@
|
||||
.makeItRed {
|
||||
background-color: red;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
startup-begin = ChatPapers is loading
|
||||
startup-finish = ChatPapers is ready
|
||||
prefs-title = ChatPapers
|
||||
|
||||
item-section-chat-head = ChatPapers
|
||||
item-section-chat-sidenav = Chat with paper
|
||||
|
||||
chat-loading = Loading ChatPapers…
|
||||
chat-placeholder = Ask a question about this paper…
|
||||
chat-send = Send
|
||||
chat-stop = Stop
|
||||
chat-summarize = Summarize
|
||||
chat-add-selection = Add selection
|
||||
chat-clear = Clear
|
||||
chat-save-note = Save as note
|
||||
chat-need-config = Configure a provider in Preferences first.
|
||||
chat-thinking = Thinking…
|
||||
chat-done = Done
|
||||
chat-stopped = Stopped
|
||||
chat-cleared = Chat cleared
|
||||
chat-no-reply = No AI reply to save yet
|
||||
chat-note-saved = Saved as note
|
||||
chat-selection-added = Selection added to next message
|
||||
chat-selection-empty = No text selected in the reader
|
||||
@@ -0,0 +1 @@
|
||||
itemmenu-label = ChatPapers: Summarize
|
||||
@@ -0,0 +1,29 @@
|
||||
prefs-title = ChatPapers
|
||||
prefs-section-provider = AI Provider
|
||||
prefs-section-generation = Generation
|
||||
prefs-section-openrouter = OpenRouter (optional)
|
||||
prefs-section-prompts = Prompts
|
||||
prefs-provider = Provider
|
||||
prefs-reset = Reset defaults
|
||||
prefs-base-url = Base URL
|
||||
prefs-api-key = API Key
|
||||
prefs-model = Model
|
||||
prefs-refresh-models = Refresh models
|
||||
prefs-temperature = Temperature
|
||||
prefs-max-tokens = Max tokens
|
||||
prefs-timeout = Timeout (ms)
|
||||
prefs-max-context = Max context chars
|
||||
prefs-answer-language = Answer language
|
||||
prefs-send-metadata =
|
||||
.label = Include item metadata in prompts
|
||||
prefs-openrouter-referer = HTTP-Referer
|
||||
prefs-openrouter-title = X-Title
|
||||
prefs-system-prompt = System prompt (leave empty for default)
|
||||
prefs-summary-prompt = Summary prompt (leave empty for default)
|
||||
prefs-hint-empty = Choose Ollama, LM Studio, OpenRouter, or another provider.
|
||||
prefs-hint-local = Local provider: requests stay on this machine. Start the server first.
|
||||
prefs-hint-openrouter = Cloud aggregator: paper text is sent to OpenRouter / upstream models.
|
||||
prefs-hint-cloud = Cloud provider: paper text is sent to the selected API endpoint.
|
||||
prefs-models-empty = No models returned.
|
||||
prefs-models-pick = Enter a model id from the list (showing up to 30):
|
||||
prefs-privacy = Privacy: ChatPapers only sends content when you click Send/Summarize, and only to the endpoint you configured. API keys are stored in local Zotero preferences.
|
||||
@@ -0,0 +1,24 @@
|
||||
startup-begin = ChatPapers 加载中
|
||||
startup-finish = ChatPapers 已就绪
|
||||
prefs-title = ChatPapers
|
||||
|
||||
item-section-chat-head = ChatPapers
|
||||
item-section-chat-sidenav = 论文对话
|
||||
|
||||
chat-loading = 正在加载 ChatPapers…
|
||||
chat-placeholder = 就这篇论文提问…
|
||||
chat-send = 发送
|
||||
chat-stop = 停止
|
||||
chat-summarize = 总结
|
||||
chat-add-selection = 添加选区
|
||||
chat-clear = 清空
|
||||
chat-save-note = 保存为笔记
|
||||
chat-need-config = 请先在偏好设置中配置 AI Provider
|
||||
chat-thinking = 思考中…
|
||||
chat-done = 完成
|
||||
chat-stopped = 已停止
|
||||
chat-cleared = 已清空对话
|
||||
chat-no-reply = 还没有可保存的 AI 回复
|
||||
chat-note-saved = 已保存为笔记
|
||||
chat-selection-added = 已将选区加入下一条消息
|
||||
chat-selection-empty = 阅读器中没有选中文本
|
||||
@@ -0,0 +1 @@
|
||||
itemmenu-label = ChatPapers:总结
|
||||
@@ -0,0 +1,29 @@
|
||||
prefs-title = ChatPapers
|
||||
prefs-section-provider = AI 接入
|
||||
prefs-section-generation = 生成参数
|
||||
prefs-section-openrouter = OpenRouter(可选)
|
||||
prefs-section-prompts = 提示词
|
||||
prefs-provider = Provider
|
||||
prefs-reset = 重置为预设默认
|
||||
prefs-base-url = Base URL
|
||||
prefs-api-key = API Key
|
||||
prefs-model = 模型
|
||||
prefs-refresh-models = 刷新模型列表
|
||||
prefs-temperature = 温度
|
||||
prefs-max-tokens = 最大 Token
|
||||
prefs-timeout = 超时(毫秒)
|
||||
prefs-max-context = 最大上下文字符
|
||||
prefs-answer-language = 回答语言
|
||||
prefs-send-metadata =
|
||||
.label = 在提示词中附带条目元数据
|
||||
prefs-openrouter-referer = HTTP-Referer
|
||||
prefs-openrouter-title = X-Title
|
||||
prefs-system-prompt = 系统提示词(留空使用默认)
|
||||
prefs-summary-prompt = 总结提示词(留空使用默认)
|
||||
prefs-hint-empty = 请选择 Ollama、LM Studio、OpenRouter 或其他 Provider。
|
||||
prefs-hint-local = 本地 Provider:请求发往本机。请先启动对应服务。
|
||||
prefs-hint-openrouter = 云端聚合:论文内容将发送到 OpenRouter / 上游模型。
|
||||
prefs-hint-cloud = 云端 Provider:论文内容将发送到所选 API 端点。
|
||||
prefs-models-empty = 未返回任何模型。
|
||||
prefs-models-pick = 从列表中输入模型 ID(最多显示 30 个):
|
||||
prefs-privacy = 隐私说明:仅在你点击发送/总结时,向你配置的端点发送内容。API Key 仅保存在本地 Zotero 偏好设置中。
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"manifest_version": 2,
|
||||
"name": "__addonName__",
|
||||
"version": "__buildVersion__",
|
||||
"description": "__description__",
|
||||
"homepage_url": "__homepage__",
|
||||
"author": "__author__",
|
||||
"icons": {
|
||||
"48": "content/icons/favicon@0.5x.png",
|
||||
"96": "content/icons/favicon.png"
|
||||
},
|
||||
"applications": {
|
||||
"zotero": {
|
||||
"id": "__addonID__",
|
||||
"update_url": "__updateURL__",
|
||||
"strict_min_version": "9.0",
|
||||
"strict_max_version": "9.*"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
pref("provider", "");
|
||||
pref("apiBaseUrl", "");
|
||||
pref("apiKey", "");
|
||||
pref("model", "");
|
||||
pref("openrouterReferer", "https://github.com/chatpapers/chatpapers");
|
||||
pref("openrouterTitle", "ChatPapers");
|
||||
pref("temperature", "0.3");
|
||||
pref("maxTokens", 2048);
|
||||
pref("timeoutMs", 120000);
|
||||
pref("maxContextChars", 80000);
|
||||
pref("answerLanguage", "zh-CN");
|
||||
pref("systemPrompt", "");
|
||||
pref("summaryPrompt", "");
|
||||
pref("sendMetadata", true);
|
||||
pref("verboseLog", false);
|
||||
Reference in New Issue
Block a user