Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
B
bit-pm
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
燕伟桐
bit-pm
Commits
af7d6fa9
Unverified
提交
af7d6fa9
authored
6月 01, 2025
作者:
Will Chen
提交者:
GitHub
6月 01, 2025
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Create ollama e2e test (#296)
上级
efb814ec
隐藏空白字符变更
内嵌
并排
正在显示
6 个修改的文件
包含
104 行增加
和
3 行删除
+104
-3
test_helper.ts
e2e-tests/helpers/test_helper.ts
+8
-0
ollama.spec.ts
e2e-tests/ollama.spec.ts
+7
-0
ollama.spec.ts_send-message-to-ollama-1.aria.yml
...napshots/ollama.spec.ts_send-message-to-ollama-1.aria.yml
+5
-0
local_model_ollama_handler.ts
src/ipc/handlers/local_model_ollama_handler.ts
+1
-1
get_model_client.ts
src/ipc/utils/get_model_client.ts
+1
-1
index.ts
testing/fake-llm-server/index.ts
+82
-1
没有找到文件。
e2e-tests/helpers/test_helper.ts
浏览文件 @
af7d6fa9
...
@@ -73,6 +73,13 @@ class PageObject {
...
@@ -73,6 +73,13 @@ class PageObject {
await
this
.
page
.
getByText
(
"test-model"
).
click
();
await
this
.
page
.
getByText
(
"test-model"
).
click
();
}
}
async
selectTestOllamaModel
()
{
await
this
.
page
.
getByRole
(
"button"
,
{
name
:
"Model: Auto"
}).
click
();
await
this
.
page
.
getByText
(
"Local models"
).
click
();
await
this
.
page
.
getByText
(
"Ollama"
,
{
exact
:
true
}).
click
();
await
this
.
page
.
getByText
(
"Testollama"
,
{
exact
:
true
}).
click
();
}
async
setUpTestProvider
()
{
async
setUpTestProvider
()
{
await
this
.
page
.
getByText
(
"Add custom providerConnect to"
).
click
();
await
this
.
page
.
getByText
(
"Add custom providerConnect to"
).
click
();
// Fill out provider dialog
// Fill out provider dialog
...
@@ -201,6 +208,7 @@ export const test = base.extend<{
...
@@ -201,6 +208,7 @@ export const test = base.extend<{
const
latestBuild
=
findLatestBuild
();
const
latestBuild
=
findLatestBuild
();
// parse the directory and find paths and other info
// parse the directory and find paths and other info
const
appInfo
=
parseElectronApp
(
latestBuild
);
const
appInfo
=
parseElectronApp
(
latestBuild
);
process
.
env
.
OLLAMA_HOST
=
"http://localhost:3500/ollama"
;
process
.
env
.
E2E_TEST_BUILD
=
"true"
;
process
.
env
.
E2E_TEST_BUILD
=
"true"
;
// This is just a hack to avoid the AI setup screen.
// This is just a hack to avoid the AI setup screen.
process
.
env
.
OPENAI_API_KEY
=
"sk-test"
;
process
.
env
.
OPENAI_API_KEY
=
"sk-test"
;
...
...
e2e-tests/ollama.spec.ts
0 → 100644
浏览文件 @
af7d6fa9
import
{
test
}
from
"./helpers/test_helper"
;
test
(
"send message to ollama"
,
async
({
po
})
=>
{
await
po
.
selectTestOllamaModel
();
await
po
.
sendPrompt
(
"hi"
);
await
po
.
snapshotMessages
();
});
e2e-tests/snapshots/ollama.spec.ts_send-message-to-ollama-1.aria.yml
0 → 100644
浏览文件 @
af7d6fa9
-
paragraph
:
hi
-
paragraph
:
ollamachunkollamachunk
-
button "Retry"
:
-
img
\ No newline at end of file
src/ipc/handlers/local_model_ollama_handler.ts
浏览文件 @
af7d6fa9
...
@@ -4,7 +4,7 @@ import { LocalModelListResponse, LocalModel } from "../ipc_types";
...
@@ -4,7 +4,7 @@ import { LocalModelListResponse, LocalModel } from "../ipc_types";
const
logger
=
log
.
scope
(
"ollama_handler"
);
const
logger
=
log
.
scope
(
"ollama_handler"
);
const
OLLAMA_API_URL
=
"http://localhost:11434"
;
const
OLLAMA_API_URL
=
process
.
env
.
OLLAMA_HOST
||
"http://localhost:11434"
;
interface
OllamaModel
{
interface
OllamaModel
{
name
:
string
;
name
:
string
;
...
...
src/ipc/utils/get_model_client.ts
浏览文件 @
af7d6fa9
...
@@ -246,7 +246,7 @@ function getRegularModelClient(
...
@@ -246,7 +246,7 @@ function getRegularModelClient(
case
"ollama"
:
{
case
"ollama"
:
{
// Ollama typically runs locally and doesn't require an API key in the same way
// Ollama typically runs locally and doesn't require an API key in the same way
const
provider
=
createOllama
({
const
provider
=
createOllama
({
baseURL
:
pro
viderConfig
.
apiBaseUrl
,
baseURL
:
pro
cess
.
env
.
OLLAMA_HOST
,
});
});
return
{
return
{
modelClient
:
{
modelClient
:
{
...
...
testing/fake-llm-server/index.ts
浏览文件 @
af7d6fa9
...
@@ -56,8 +56,89 @@ app.get("/health", (req, res) => {
...
@@ -56,8 +56,89 @@ app.get("/health", (req, res) => {
res
.
send
(
"OK"
);
res
.
send
(
"OK"
);
});
});
// Ollama-specific endpoints
app
.
get
(
"/ollama/api/tags"
,
(
req
,
res
)
=>
{
const
ollamaModels
=
{
models
:
[
{
name
:
"testollama"
,
modified_at
:
"2024-05-01T10:00:00.000Z"
,
size
:
4700000000
,
digest
:
"abcdef123456"
,
details
:
{
format
:
"gguf"
,
family
:
"llama"
,
families
:
[
"llama"
],
parameter_size
:
"8B"
,
quantization_level
:
"Q4_0"
,
},
},
{
name
:
"codellama:7b"
,
modified_at
:
"2024-04-25T12:30:00.000Z"
,
size
:
3800000000
,
digest
:
"fedcba654321"
,
details
:
{
format
:
"gguf"
,
family
:
"llama"
,
families
:
[
"llama"
,
"codellama"
],
parameter_size
:
"7B"
,
quantization_level
:
"Q5_K_M"
,
},
},
],
};
console
.
log
(
"* Sending fake Ollama models"
);
res
.
json
(
ollamaModels
);
});
let
globalCounter
=
0
;
let
globalCounter
=
0
;
app
.
post
(
"/ollama/chat"
,
(
req
,
res
)
=>
{
// Tell the client we’re going to stream NDJSON
res
.
setHeader
(
"Content-Type"
,
"application/x-ndjson"
);
res
.
setHeader
(
"Cache-Control"
,
"no-cache"
);
// Chunk #1 – partial answer
const
firstChunk
=
{
model
:
"llama3.2"
,
created_at
:
"2023-08-04T08:52:19.385406455-07:00"
,
message
:
{
role
:
"assistant"
,
content
:
"ollamachunk"
,
images
:
null
,
},
done
:
false
,
};
// Chunk #2 – final answer + metrics
const
secondChunk
=
{
model
:
"llama3.2"
,
created_at
:
"2023-08-04T19:22:45.499127Z"
,
message
:
{
role
:
"assistant"
,
content
:
""
,
},
done
:
true
,
total_duration
:
4883583458
,
load_duration
:
1334875
,
prompt_eval_count
:
26
,
prompt_eval_duration
:
342546000
,
eval_count
:
282
,
eval_duration
:
4535599000
,
};
// Send the first object right away
res
.
write
(
JSON
.
stringify
(
firstChunk
)
+
"
\
n"
);
res
.
write
(
JSON
.
stringify
(
firstChunk
)
+
"
\
n"
);
// …and the second one a moment later to mimic streaming
setTimeout
(()
=>
{
res
.
write
(
JSON
.
stringify
(
secondChunk
)
+
"
\
n"
);
res
.
end
();
// Close the HTTP stream
},
300
);
// 300 ms delay – tweak as you like
});
// Handle POST requests to /v1/chat/completions
// Handle POST requests to /v1/chat/completions
app
.
post
(
"/v1/chat/completions"
,
(
req
,
res
)
=>
{
app
.
post
(
"/v1/chat/completions"
,
(
req
,
res
)
=>
{
const
{
stream
=
false
,
messages
=
[]
}
=
req
.
body
;
const
{
stream
=
false
,
messages
=
[]
}
=
req
.
body
;
...
@@ -188,7 +269,7 @@ app.post("/v1/chat/completions", (req, res) => {
...
@@ -188,7 +269,7 @@ app.post("/v1/chat/completions", (req, res) => {
clearInterval
(
interval
);
clearInterval
(
interval
);
res
.
end
();
res
.
end
();
}
}
},
1
);
},
1
0
);
});
});
// Start the server
// Start the server
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论