opencode-fixes-huihui 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +53 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +60 -0
- package/dist/index.js.map +1 -0
- package/package.json +51 -0
package/README.md
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# opencode-fixes-huihui
|
|
2
|
+
|
|
3
|
+
opencode 单插件版本:统一处理 sticky session headers 和 `promptCacheKey`,用于稳定会话路由与缓存命中。
|
|
4
|
+
|
|
5
|
+
## 安装
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm i opencode-fixes-huihui
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## 使用
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import StickySessionPlugin from "opencode-fixes-huihui";
|
|
15
|
+
|
|
16
|
+
export default {
|
|
17
|
+
plugins: [StickySessionPlugin],
|
|
18
|
+
};
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
也可使用具名导出:
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
import { StickySessionPlugin } from "opencode-fixes-huihui";
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## 行为
|
|
28
|
+
|
|
29
|
+
插件在 `chat.params` 中执行:
|
|
30
|
+
|
|
31
|
+
1. 仅对 `@ai-sdk/openai` provider 生效
|
|
32
|
+
2. 解析会话值优先级:
|
|
33
|
+
- `OPENCODE_PROMPT_CACHE_KEY`
|
|
34
|
+
- `OPENCODE_STICKY_SESSION_ID`
|
|
35
|
+
- 现有 headers:`x-session-id` / `conversation_id` / `session_id`
|
|
36
|
+
- `input.sessionID`
|
|
37
|
+
3. 将解析值同时写入:
|
|
38
|
+
- `input.model.headers.x-session-id`
|
|
39
|
+
- `input.model.headers.conversation_id`
|
|
40
|
+
- `input.model.headers.session_id`
|
|
41
|
+
- `output.options.promptCacheKey`
|
|
42
|
+
|
|
43
|
+
## 可选环境变量
|
|
44
|
+
|
|
45
|
+
- `OPENCODE_PROMPT_CACHE_KEY`: 强制覆盖会话值(最高优先级)
|
|
46
|
+
- `OPENCODE_STICKY_SESSION_ID`: 次优先级覆盖会话值
|
|
47
|
+
|
|
48
|
+
## 开发
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
npm run typecheck
|
|
52
|
+
npm run build
|
|
53
|
+
```
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Plugin } from "@opencode-ai/plugin";
|
|
2
|
+
/**
|
|
3
|
+
* set a session-scoped prompt cache key and session-scoped sticky routing headers for right.codes.
|
|
4
|
+
*
|
|
5
|
+
* Injects HTTP headers via `input.model.headers` so upstream proxies/load
|
|
6
|
+
* balancers can keep a conversation pinned to one account.
|
|
7
|
+
*
|
|
8
|
+
* Headers injected for @ai-sdk/openai providers:
|
|
9
|
+
* - x-session-id
|
|
10
|
+
* - conversation_id
|
|
11
|
+
* - session_id
|
|
12
|
+
*
|
|
13
|
+
* Source of truth (in order):
|
|
14
|
+
* - env: OPENCODE_PROMPT_CACHE_KEY (manual override)
|
|
15
|
+
* - env: OPENCODE_STICKY_SESSION_ID (manual override)
|
|
16
|
+
* - model headers (x-session-id / conversation_id / session_id)
|
|
17
|
+
* - opencode sessionID (default)
|
|
18
|
+
*/
|
|
19
|
+
export declare const StickySessionPlugin: Plugin;
|
|
20
|
+
export default StickySessionPlugin;
|
|
21
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AA2BlD;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,mBAAmB,EAAE,MAsBjC,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
const OPENAI_PROVIDER_NPM = "@ai-sdk/openai";
|
|
2
|
+
const OPENAI_PROVIDER_ID = "openai";
|
|
3
|
+
const SESSION_HEADER_KEYS = ["x-session-id", "conversation_id", "session_id"];
|
|
4
|
+
const normalize = (value) => (typeof value === "string" ? value.trim() : "");
|
|
5
|
+
const pickHeaderSessionValue = (headers) => {
|
|
6
|
+
for (const key of SESSION_HEADER_KEYS) {
|
|
7
|
+
const value = normalize(headers[key]);
|
|
8
|
+
if (value)
|
|
9
|
+
return value;
|
|
10
|
+
}
|
|
11
|
+
return "";
|
|
12
|
+
};
|
|
13
|
+
const ensureHeaders = (model) => {
|
|
14
|
+
if (model.headers && typeof model.headers === "object") {
|
|
15
|
+
return model.headers;
|
|
16
|
+
}
|
|
17
|
+
const headers = {};
|
|
18
|
+
model.headers = headers;
|
|
19
|
+
return headers;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* set a session-scoped prompt cache key and session-scoped sticky routing headers for right.codes.
|
|
23
|
+
*
|
|
24
|
+
* Injects HTTP headers via `input.model.headers` so upstream proxies/load
|
|
25
|
+
* balancers can keep a conversation pinned to one account.
|
|
26
|
+
*
|
|
27
|
+
* Headers injected for @ai-sdk/openai providers:
|
|
28
|
+
* - x-session-id
|
|
29
|
+
* - conversation_id
|
|
30
|
+
* - session_id
|
|
31
|
+
*
|
|
32
|
+
* Source of truth (in order):
|
|
33
|
+
* - env: OPENCODE_PROMPT_CACHE_KEY (manual override)
|
|
34
|
+
* - env: OPENCODE_STICKY_SESSION_ID (manual override)
|
|
35
|
+
* - model headers (x-session-id / conversation_id / session_id)
|
|
36
|
+
* - opencode sessionID (default)
|
|
37
|
+
*/
|
|
38
|
+
export const StickySessionPlugin = async () => {
|
|
39
|
+
const envPromptCacheKey = normalize(process.env.OPENCODE_PROMPT_CACHE_KEY);
|
|
40
|
+
const envStickySessionID = normalize(process.env.OPENCODE_STICKY_SESSION_ID);
|
|
41
|
+
const envOverride = envPromptCacheKey || envStickySessionID;
|
|
42
|
+
return {
|
|
43
|
+
"chat.params": async (input, output) => {
|
|
44
|
+
const providerNpm = normalize(input.model.api.npm);
|
|
45
|
+
const providerID = normalize(input.provider.info.id);
|
|
46
|
+
if (!providerNpm.includes(OPENAI_PROVIDER_NPM) && providerID !== OPENAI_PROVIDER_ID)
|
|
47
|
+
return;
|
|
48
|
+
const headers = ensureHeaders(input.model);
|
|
49
|
+
const sessionValue = envOverride || pickHeaderSessionValue(headers) || normalize(input.sessionID);
|
|
50
|
+
if (!sessionValue)
|
|
51
|
+
return;
|
|
52
|
+
for (const key of SESSION_HEADER_KEYS) {
|
|
53
|
+
headers[key] = sessionValue;
|
|
54
|
+
}
|
|
55
|
+
output.options.promptCacheKey = sessionValue;
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
export default StickySessionPlugin;
|
|
60
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAEA,MAAM,mBAAmB,GAAG,gBAAgB,CAAC;AAC7C,MAAM,kBAAkB,GAAG,QAAQ,CAAC;AACpC,MAAM,mBAAmB,GAAG,CAAC,cAAc,EAAE,iBAAiB,EAAE,YAAY,CAAU,CAAC;AAIvF,MAAM,SAAS,GAAG,CAAC,KAAc,EAAU,EAAE,CAAC,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AAE9F,MAAM,sBAAsB,GAAG,CAAC,OAAkB,EAAU,EAAE;IAC5D,KAAK,MAAM,GAAG,IAAI,mBAAmB,EAAE,CAAC;QACtC,MAAM,KAAK,GAAG,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;QACtC,IAAI,KAAK;YAAE,OAAO,KAAK,CAAC;IAC1B,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC,CAAC;AAEF,MAAM,aAAa,GAAG,CAAC,KAA4B,EAAa,EAAE;IAChE,IAAI,KAAK,CAAC,OAAO,IAAI,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;QACvD,OAAO,KAAK,CAAC,OAAoB,CAAC;IACpC,CAAC;IACD,MAAM,OAAO,GAAc,EAAE,CAAC;IAC9B,KAAK,CAAC,OAAO,GAAG,OAAO,CAAC;IACxB,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAW,KAAK,IAAI,EAAE;IACpD,MAAM,iBAAiB,GAAG,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;IAC3E,MAAM,kBAAkB,GAAG,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;IAC7E,MAAM,WAAW,GAAG,iBAAiB,IAAI,kBAAkB,CAAC;IAE5D,OAAO;QACL,aAAa,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;YACrC,MAAM,WAAW,GAAG,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACnD,MAAM,UAAU,GAAG,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACrD,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,mBAAmB,CAAC,IAAI,UAAU,KAAK,kBAAkB;gBAAE,OAAO;YAE5F,MAAM,OAAO,GAAG,aAAa,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAC3C,MAAM,YAAY,GAAG,WAAW,IAAI,sBAAsB,CAAC,OAAO,CAAC,IAAI,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;YAClG,IAAI,CAAC,YAAY;gBAAE,OAAO;YAE1B,KAAK,MAAM,GAAG,IAAI,mBAAmB,EAAE,CAAC;gBACtC,OAAO,CAAC,GAAG,CAAC,GAAG,YAAY,CAAC;YAC9B,CAAC;YAED,MAAM,CAAC,OAAO,CAAC,cAAc,GAAG,YAAY,CAAC;QAC/C,CAAC;KACF,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "opencode-fixes-huihui",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Unified sticky-session plugin for opencode with session headers and prompt cache key.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"private": false,
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"module": "./dist/index.js",
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"import": "./dist/index.js",
|
|
14
|
+
"default": "./dist/index.js"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist",
|
|
19
|
+
"README.md"
|
|
20
|
+
],
|
|
21
|
+
"scripts": {
|
|
22
|
+
"typecheck": "tsc --noEmit",
|
|
23
|
+
"build": "tsc -p tsconfig.json",
|
|
24
|
+
"prepublishOnly": "npm run typecheck && npm run build"
|
|
25
|
+
},
|
|
26
|
+
"keywords": [
|
|
27
|
+
"opencode",
|
|
28
|
+
"plugin",
|
|
29
|
+
"session",
|
|
30
|
+
"sticky-session",
|
|
31
|
+
"prompt-cache"
|
|
32
|
+
],
|
|
33
|
+
"author": "huihuimoe",
|
|
34
|
+
"license": "MIT",
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "git+https://huihui.cat/huihui/opencode-fixes-huihui.git"
|
|
38
|
+
},
|
|
39
|
+
"homepage": "https://huihui.cat/huihui/opencode-fixes-huihui",
|
|
40
|
+
"bugs": {
|
|
41
|
+
"url": "https://huihui.cat/huihui/opencode-fixes-huihui/-/issues"
|
|
42
|
+
},
|
|
43
|
+
"engines": {
|
|
44
|
+
"node": ">=18"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@opencode-ai/plugin": "^1.2.6",
|
|
48
|
+
"@types/node": "^25.2.3",
|
|
49
|
+
"typescript": "^5.9.2"
|
|
50
|
+
}
|
|
51
|
+
}
|