@kevisual/router 0.0.74 → 0.0.75

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.
@@ -1,6 +1,7 @@
1
1
  import { app, createSkill, tool } from '../app.ts';
2
2
  import * as docs from '../gen/index.ts'
3
3
  import * as pkgs from '../../package.json' assert { type: 'json' };
4
+ import z from 'zod';
4
5
  app.route({
5
6
  path: 'router-skill',
6
7
  key: 'create-route',
@@ -32,14 +33,47 @@ app.route({
32
33
  }
33
34
  }).addTo(app);
34
35
 
35
- // 调用router应用 path router-skill key version
36
+ // 获取最新router版本号
36
37
  app.route({
37
38
  path: 'router-skill',
38
39
  key: 'version',
39
- description: '获取路由技能版本',
40
+ description: '获取最新router版本号',
40
41
  middleware: ['auth'],
42
+ metadata: {
43
+ tags: ['opencode'],
44
+ ...createSkill({
45
+ skill: 'router-skill-version',
46
+ title: '获取最新router版本号',
47
+ summary: '获取最新router版本号',
48
+ args: {}
49
+ })
50
+ },
41
51
  }).define(async (ctx) => {
42
52
  ctx.body = {
43
53
  content: pkgs.version || 'unknown'
44
54
  }
45
- }).addTo(app);
55
+ }).addTo(app);
56
+
57
+ // 执行技能test-route-skill,name为abearxiong
58
+ app.route({
59
+ path: 'route-skill',
60
+ key: 'test',
61
+ description: '测试路由技能',
62
+ middleware: ['auth'],
63
+ metadata: {
64
+ tags: ['opencode'],
65
+ ...createSkill({
66
+ skill: 'test-route-skill',
67
+ title: '测试路由技能',
68
+ summary: '测试路由技能是否正常工作',
69
+ args: z.object({
70
+ name: z.string().describe('名字'),
71
+ })
72
+ })
73
+ },
74
+ }).define(async (ctx) => {
75
+ const name = ctx.query.name || 'unknown';
76
+ ctx.body = {
77
+ content: '测试成功,你好 ' + name
78
+ }
79
+ }).addTo(app)
package/dist/app.js CHANGED
@@ -16745,6 +16745,9 @@ function date4(params) {
16745
16745
 
16746
16746
  // node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/classic/external.js
16747
16747
  config(en_default());
16748
+ // node_modules/.pnpm/zod@4.3.6/node_modules/zod/index.js
16749
+ var zod_default = exports_external;
16750
+
16748
16751
  // node_modules/.pnpm/nanoid@5.1.6/node_modules/nanoid/index.js
16749
16752
  import { webcrypto as crypto } from "node:crypto";
16750
16753
  var POOL_SIZE_MULTIPLIER = 128;
@@ -16799,6 +16802,12 @@ var tool = {
16799
16802
  schema: exports_external
16800
16803
  };
16801
16804
  var createSkill = (skill) => {
16805
+ if (skill.tags) {
16806
+ const hasOpencode = skill.tags.includes("opencode");
16807
+ if (!hasOpencode) {
16808
+ skill.tags.push("opencode");
16809
+ }
16810
+ }
16802
16811
  return {
16803
16812
  args: {},
16804
16813
  ...skill
@@ -16919,6 +16928,10 @@ var toJSONSchema2 = (route) => {
16919
16928
  const pickValues = pick(route, pickValue);
16920
16929
  if (pickValues?.metadata?.args) {
16921
16930
  const args = pickValues.metadata.args;
16931
+ if (args && typeof args === "object" && args.toJSONSchema && typeof args.toJSONSchema === "function") {
16932
+ pickValues.metadata.args = args.toJSONSchema();
16933
+ return pickValues;
16934
+ }
16922
16935
  const keys = Object.keys(args);
16923
16936
  const newArgs = {};
16924
16937
  for (let key of keys) {
@@ -16937,6 +16950,10 @@ var fromJSONSchema2 = (route) => {
16937
16950
  const args = route?.metadata?.args;
16938
16951
  if (!args)
16939
16952
  return route;
16953
+ if (args["$schema"] || args.type === "object" && args.properties && typeof args.properties === "object") {
16954
+ route.metadata.args = exports_external.fromJSONSchema(args);
16955
+ return route;
16956
+ }
16940
16957
  const keys = Object.keys(args);
16941
16958
  const newArgs = {};
16942
16959
  for (let key of keys) {
@@ -19175,8 +19192,12 @@ var addCallFn = (app2) => {
19175
19192
  tags: ["opencode"],
19176
19193
  ...createSkill({
19177
19194
  skill: "call-app",
19178
- title: "调用app应用",
19179
- summary: "调用router的应用, 参数path, key, payload",
19195
+ title: "调用app应用,非技能模块",
19196
+ summary: `调用router的应用(非技能模块),适用于需要直接调用应用而不是技能的场景
19197
+ 条件1: 参数path(string), key(string), payload(object)
19198
+ 条件2: 当前的应用调用的模式不是技能
19199
+
19200
+ `,
19180
19201
  args: {
19181
19202
  path: tool.schema.string().describe("应用路径,例如 cnb"),
19182
19203
  key: tool.schema.string().optional().describe("应用key,例如 list-repos"),
@@ -19196,6 +19217,7 @@ var addCallFn = (app2) => {
19196
19217
  }).addTo(app2);
19197
19218
  };
19198
19219
  var createRouterAgentPluginFn = (opts) => {
19220
+ new Promise((resolve) => setTimeout(resolve, 100));
19199
19221
  let router = opts?.router;
19200
19222
  if (!router) {
19201
19223
  const app2 = useContextKey("app");
@@ -19213,6 +19235,9 @@ var createRouterAgentPluginFn = (opts) => {
19213
19235
  const _routes = filter(router.routes, opts?.query || "");
19214
19236
  const routes = _routes.filter((r) => {
19215
19237
  const metadata = r.metadata;
19238
+ if (metadata && metadata.skill && metadata.summary) {
19239
+ return true;
19240
+ }
19216
19241
  if (metadata && metadata.tags && metadata.tags.includes("opencode")) {
19217
19242
  return !!metadata.skill;
19218
19243
  }
@@ -19226,15 +19251,16 @@ var createRouterAgentPluginFn = (opts) => {
19226
19251
  tool: {
19227
19252
  ...routes.reduce((acc, route) => {
19228
19253
  const metadata = route.metadata;
19254
+ let args = extractArgs(metadata?.args);
19229
19255
  acc[metadata.skill] = {
19230
19256
  name: metadata.title || metadata.skill,
19231
19257
  description: metadata.summary || "",
19232
- args: metadata.args || {},
19233
- async execute(args) {
19258
+ args,
19259
+ async execute(args2) {
19234
19260
  const res = await router.run({
19235
19261
  path: route.path,
19236
19262
  key: route.key,
19237
- payload: args
19263
+ payload: args2
19238
19264
  }, { appId: router.appId });
19239
19265
  if (res.code === 200) {
19240
19266
  if (res.data?.content) {
@@ -19261,6 +19287,12 @@ var createRouterAgentPluginFn = (opts) => {
19261
19287
  };
19262
19288
  return AgentPlugin;
19263
19289
  };
19290
+ var extractArgs = (args) => {
19291
+ if (args && typeof args === "object" && typeof args.shape === "object") {
19292
+ return args.shape;
19293
+ }
19294
+ return args || {};
19295
+ };
19264
19296
 
19265
19297
  // agent/gen/index.ts
19266
19298
  var readme = `# router
@@ -19453,7 +19485,7 @@ app
19453
19485
  10. **中间件找不到会返回 404**,错误信息中会包含找不到的中间件列表。
19454
19486
  `;
19455
19487
  // package.json
19456
- var version2 = "0.0.74";
19488
+ var version2 = "0.0.75";
19457
19489
 
19458
19490
  // agent/routes/route-create.ts
19459
19491
  app.route({
@@ -19493,13 +19525,44 @@ app.route({
19493
19525
  app.route({
19494
19526
  path: "router-skill",
19495
19527
  key: "version",
19496
- description: "获取路由技能版本",
19497
- middleware: ["auth"]
19528
+ description: "获取最新router版本号",
19529
+ middleware: ["auth"],
19530
+ metadata: {
19531
+ tags: ["opencode"],
19532
+ ...createSkill({
19533
+ skill: "router-skill-version",
19534
+ title: "获取最新router版本号",
19535
+ summary: "获取最新router版本号",
19536
+ args: {}
19537
+ })
19538
+ }
19498
19539
  }).define(async (ctx) => {
19499
19540
  ctx.body = {
19500
19541
  content: version2 || "unknown"
19501
19542
  };
19502
19543
  }).addTo(app);
19544
+ app.route({
19545
+ path: "route-skill",
19546
+ key: "test",
19547
+ description: "测试路由技能",
19548
+ middleware: ["auth"],
19549
+ metadata: {
19550
+ tags: ["opencode"],
19551
+ ...createSkill({
19552
+ skill: "test-route-skill",
19553
+ title: "测试路由技能",
19554
+ summary: "测试路由技能是否正常工作",
19555
+ args: zod_default.object({
19556
+ name: zod_default.string().describe("名字")
19557
+ })
19558
+ })
19559
+ }
19560
+ }).define(async (ctx) => {
19561
+ const name = ctx.query.name || "unknown";
19562
+ ctx.body = {
19563
+ content: "测试成功,你好 " + name
19564
+ };
19565
+ }).addTo(app);
19503
19566
 
19504
19567
  // agent/routes/index.ts
19505
19568
  if (!app.hasRoute("auth", "")) {
@@ -719,5 +719,12 @@ declare const createRouterAgentPluginFn: (opts?: {
719
719
  hooks?: (plugin: PluginInput) => Promise<Hooks>;
720
720
  }) => Plugin;
721
721
  declare const usePluginInput: () => PluginInput;
722
+ /**
723
+ * 如果args是z.object类型,拆分第一个Object的属性,比如z.object({ name: z.string(), age: z.number() }),拆分成{name: z.string(), age: z.number()}
724
+ * 如果args是普通对象,直接返回
725
+ * @param args
726
+ * @returns
727
+ */
728
+ declare const extractArgs: (args: any) => any;
722
729
 
723
- export { addCallFn, createRouterAgentPluginFn, usePluginInput };
730
+ export { addCallFn, createRouterAgentPluginFn, extractArgs, usePluginInput };
package/dist/opencode.js CHANGED
@@ -14339,6 +14339,12 @@ var tool = {
14339
14339
  schema: exports_external
14340
14340
  };
14341
14341
  var createSkill = (skill) => {
14342
+ if (skill.tags) {
14343
+ const hasOpencode = skill.tags.includes("opencode");
14344
+ if (!hasOpencode) {
14345
+ skill.tags.push("opencode");
14346
+ }
14347
+ }
14342
14348
  return {
14343
14349
  args: {},
14344
14350
  ...skill
@@ -14699,8 +14705,12 @@ var addCallFn = (app) => {
14699
14705
  tags: ["opencode"],
14700
14706
  ...createSkill({
14701
14707
  skill: "call-app",
14702
- title: "调用app应用",
14703
- summary: "调用router的应用, 参数path, key, payload",
14708
+ title: "调用app应用,非技能模块",
14709
+ summary: `调用router的应用(非技能模块),适用于需要直接调用应用而不是技能的场景
14710
+ 条件1: 参数path(string), key(string), payload(object)
14711
+ 条件2: 当前的应用调用的模式不是技能
14712
+
14713
+ `,
14704
14714
  args: {
14705
14715
  path: tool.schema.string().describe("应用路径,例如 cnb"),
14706
14716
  key: tool.schema.string().optional().describe("应用key,例如 list-repos"),
@@ -14720,6 +14730,7 @@ var addCallFn = (app) => {
14720
14730
  }).addTo(app);
14721
14731
  };
14722
14732
  var createRouterAgentPluginFn = (opts) => {
14733
+ new Promise((resolve) => setTimeout(resolve, 100));
14723
14734
  let router = opts?.router;
14724
14735
  if (!router) {
14725
14736
  const app = useContextKey("app");
@@ -14737,6 +14748,9 @@ var createRouterAgentPluginFn = (opts) => {
14737
14748
  const _routes = filter(router.routes, opts?.query || "");
14738
14749
  const routes = _routes.filter((r) => {
14739
14750
  const metadata = r.metadata;
14751
+ if (metadata && metadata.skill && metadata.summary) {
14752
+ return true;
14753
+ }
14740
14754
  if (metadata && metadata.tags && metadata.tags.includes("opencode")) {
14741
14755
  return !!metadata.skill;
14742
14756
  }
@@ -14750,15 +14764,16 @@ var createRouterAgentPluginFn = (opts) => {
14750
14764
  tool: {
14751
14765
  ...routes.reduce((acc, route) => {
14752
14766
  const metadata = route.metadata;
14767
+ let args = extractArgs(metadata?.args);
14753
14768
  acc[metadata.skill] = {
14754
14769
  name: metadata.title || metadata.skill,
14755
14770
  description: metadata.summary || "",
14756
- args: metadata.args || {},
14757
- async execute(args) {
14771
+ args,
14772
+ async execute(args2) {
14758
14773
  const res = await router.run({
14759
14774
  path: route.path,
14760
14775
  key: route.key,
14761
- payload: args
14776
+ payload: args2
14762
14777
  }, { appId: router.appId });
14763
14778
  if (res.code === 200) {
14764
14779
  if (res.data?.content) {
@@ -14788,8 +14803,15 @@ var createRouterAgentPluginFn = (opts) => {
14788
14803
  var usePluginInput = () => {
14789
14804
  return useContextKey("plugin-input");
14790
14805
  };
14806
+ var extractArgs = (args) => {
14807
+ if (args && typeof args === "object" && typeof args.shape === "object") {
14808
+ return args.shape;
14809
+ }
14810
+ return args || {};
14811
+ };
14791
14812
  export {
14792
14813
  usePluginInput,
14814
+ extractArgs,
14793
14815
  createRouterAgentPluginFn,
14794
14816
  addCallFn
14795
14817
  };
@@ -149,6 +149,7 @@ type Skill<T = SimpleObject$1> = {
149
149
  skill: string;
150
150
  title: string;
151
151
  summary?: string;
152
+ tags?: string[];
152
153
  args?: {
153
154
  [key: string]: any;
154
155
  };
@@ -13966,6 +13966,12 @@ var tool = {
13966
13966
  schema: exports_external
13967
13967
  };
13968
13968
  var createSkill = (skill) => {
13969
+ if (skill.tags) {
13970
+ const hasOpencode = skill.tags.includes("opencode");
13971
+ if (!hasOpencode) {
13972
+ skill.tags.push("opencode");
13973
+ }
13974
+ }
13969
13975
  return {
13970
13976
  args: {},
13971
13977
  ...skill
@@ -14086,6 +14092,10 @@ var toJSONSchema2 = (route) => {
14086
14092
  const pickValues = pick(route, pickValue);
14087
14093
  if (pickValues?.metadata?.args) {
14088
14094
  const args = pickValues.metadata.args;
14095
+ if (args && typeof args === "object" && args.toJSONSchema && typeof args.toJSONSchema === "function") {
14096
+ pickValues.metadata.args = args.toJSONSchema();
14097
+ return pickValues;
14098
+ }
14089
14099
  const keys = Object.keys(args);
14090
14100
  const newArgs = {};
14091
14101
  for (let key of keys) {
@@ -14104,6 +14114,10 @@ var fromJSONSchema2 = (route) => {
14104
14114
  const args = route?.metadata?.args;
14105
14115
  if (!args)
14106
14116
  return route;
14117
+ if (args["$schema"] || args.type === "object" && args.properties && typeof args.properties === "object") {
14118
+ route.metadata.args = exports_external.fromJSONSchema(args);
14119
+ return route;
14120
+ }
14107
14121
  const keys = Object.keys(args);
14108
14122
  const newArgs = {};
14109
14123
  for (let key of keys) {
package/dist/router.d.ts CHANGED
@@ -155,6 +155,7 @@ type Skill<T = SimpleObject$1> = {
155
155
  skill: string;
156
156
  title: string;
157
157
  summary?: string;
158
+ tags?: string[];
158
159
  args?: {
159
160
  [key: string]: any;
160
161
  };
package/dist/router.js CHANGED
@@ -16799,6 +16799,12 @@ var tool = {
16799
16799
  schema: exports_external
16800
16800
  };
16801
16801
  var createSkill = (skill) => {
16802
+ if (skill.tags) {
16803
+ const hasOpencode = skill.tags.includes("opencode");
16804
+ if (!hasOpencode) {
16805
+ skill.tags.push("opencode");
16806
+ }
16807
+ }
16802
16808
  return {
16803
16809
  args: {},
16804
16810
  ...skill
@@ -16919,6 +16925,10 @@ var toJSONSchema2 = (route) => {
16919
16925
  const pickValues = pick(route, pickValue);
16920
16926
  if (pickValues?.metadata?.args) {
16921
16927
  const args = pickValues.metadata.args;
16928
+ if (args && typeof args === "object" && args.toJSONSchema && typeof args.toJSONSchema === "function") {
16929
+ pickValues.metadata.args = args.toJSONSchema();
16930
+ return pickValues;
16931
+ }
16922
16932
  const keys = Object.keys(args);
16923
16933
  const newArgs = {};
16924
16934
  for (let key of keys) {
@@ -16937,6 +16947,10 @@ var fromJSONSchema2 = (route) => {
16937
16947
  const args = route?.metadata?.args;
16938
16948
  if (!args)
16939
16949
  return route;
16950
+ if (args["$schema"] || args.type === "object" && args.properties && typeof args.properties === "object") {
16951
+ route.metadata.args = exports_external.fromJSONSchema(args);
16952
+ return route;
16953
+ }
16940
16954
  const keys = Object.keys(args);
16941
16955
  const newArgs = {};
16942
16956
  for (let key of keys) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package",
3
3
  "name": "@kevisual/router",
4
- "version": "0.0.74",
4
+ "version": "0.0.75",
5
5
  "description": "",
6
6
  "type": "module",
7
7
  "main": "./dist/router.js",
@@ -28,7 +28,7 @@
28
28
  "@kevisual/dts": "^0.0.4",
29
29
  "@kevisual/js-filter": "^0.0.5",
30
30
  "@kevisual/local-proxy": "^0.0.8",
31
- "@kevisual/query": "^0.0.43",
31
+ "@kevisual/query": "^0.0.46",
32
32
  "@kevisual/use-config": "^1.0.30",
33
33
  "@opencode-ai/plugin": "^1.2.6",
34
34
  "@types/bun": "^1.3.9",
package/src/opencode.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { useContextKey } from '@kevisual/context'
2
- import { createSkill, type QueryRouterServer, tool, type QueryRouter, type Skill } from './route.ts'
2
+ import { createSkill, type QueryRouterServer, tool, type Skill } from './route.ts'
3
3
  import { type App } from './app.ts'
4
4
  import { PluginInput, type Plugin, Hooks } from "@opencode-ai/plugin"
5
5
 
@@ -15,8 +15,12 @@ export const addCallFn = (app: App) => {
15
15
  tags: ['opencode'],
16
16
  ...createSkill({
17
17
  skill: 'call-app',
18
- title: '调用app应用',
19
- summary: '调用router的应用, 参数path, key, payload',
18
+ title: '调用app应用,非技能模块',
19
+ summary: `调用router的应用(非技能模块),适用于需要直接调用应用而不是技能的场景
20
+ 条件1: 参数path(string), key(string), payload(object)
21
+ 条件2: 当前的应用调用的模式不是技能
22
+
23
+ `,
20
24
  args: {
21
25
  path: tool.schema.string().describe('应用路径,例如 cnb'),
22
26
  key: tool.schema.string().optional().describe('应用key,例如 list-repos'),
@@ -42,7 +46,9 @@ export const createRouterAgentPluginFn = (opts?: {
42
46
  query?: string,
43
47
  hooks?: (plugin: PluginInput) => Promise<Hooks>
44
48
  }) => {
49
+ new Promise(resolve => setTimeout(resolve, 100)) // 等待路由加载
45
50
  let router = opts?.router
51
+
46
52
  if (!router) {
47
53
  const app = useContextKey<App>('app')
48
54
  router = app
@@ -59,13 +65,15 @@ export const createRouterAgentPluginFn = (opts?: {
59
65
  const _routes = filter(router.routes, opts?.query || '')
60
66
  const routes = _routes.filter(r => {
61
67
  const metadata = r.metadata as Skill
68
+ if (metadata && metadata.skill && metadata.summary) {
69
+ return true
70
+ }
62
71
  if (metadata && metadata.tags && metadata.tags.includes('opencode')) {
63
72
  return !!metadata.skill
64
73
  }
65
74
  return false
66
75
  });
67
-
68
- // opencode run "查看系统信息"
76
+ // opencode run "使用技能查看系统信息"
69
77
  const AgentPlugin: Plugin = async (pluginInput) => {
70
78
  useContextKey<PluginInput>('plugin-input', () => pluginInput, true)
71
79
  const hooks = opts?.hooks ? await opts.hooks(pluginInput) : {}
@@ -74,10 +82,11 @@ export const createRouterAgentPluginFn = (opts?: {
74
82
  'tool': {
75
83
  ...routes.reduce((acc, route) => {
76
84
  const metadata = route.metadata as Skill
85
+ let args = extractArgs(metadata?.args)
77
86
  acc[metadata.skill!] = {
78
87
  name: metadata.title || metadata.skill,
79
88
  description: metadata.summary || '',
80
- args: metadata.args || {},
89
+ args: args,
81
90
  async execute(args: Record<string, any>) {
82
91
  const res = await router.run({
83
92
  path: route.path,
@@ -117,4 +126,17 @@ export const createRouterAgentPluginFn = (opts?: {
117
126
 
118
127
  export const usePluginInput = (): PluginInput => {
119
128
  return useContextKey<PluginInput>('plugin-input')
129
+ }
130
+
131
+ /**
132
+ * 如果args是z.object类型,拆分第一个Object的属性,比如z.object({ name: z.string(), age: z.number() }),拆分成{name: z.string(), age: z.number()}
133
+ * 如果args是普通对象,直接返回
134
+ * @param args
135
+ * @returns
136
+ */
137
+ export const extractArgs = (args: any) => {
138
+ if (args && typeof args === 'object' && typeof args.shape === 'object') {
139
+ return args.shape
140
+ }
141
+ return args || {}
120
142
  }
package/src/route.ts CHANGED
@@ -97,6 +97,7 @@ export type Skill<T = SimpleObject> = {
97
97
  skill: string;
98
98
  title: string;
99
99
  summary?: string;
100
+ tags?: string[];
100
101
  args?: {
101
102
  [key: string]: any
102
103
  };
@@ -106,6 +107,12 @@ export const tool = {
106
107
  }
107
108
  /** */
108
109
  export const createSkill = <T = SimpleObject>(skill: Skill<T>): Skill<T> => {
110
+ if (skill.tags) {
111
+ const hasOpencode = skill.tags.includes('opencode');
112
+ if (!hasOpencode) {
113
+ skill.tags.push('opencode');
114
+ }
115
+ }
109
116
  return {
110
117
  args: {},
111
118
  ...skill
@@ -247,6 +254,10 @@ export const toJSONSchema = (route: RouteInfo) => {
247
254
  const pickValues = pick(route, pickValue as any);
248
255
  if (pickValues?.metadata?.args) {
249
256
  const args = pickValues.metadata.args;
257
+ if (args && typeof args === 'object' && args.toJSONSchema && typeof args.toJSONSchema === 'function') {
258
+ pickValues.metadata.args = args.toJSONSchema();
259
+ return pickValues;
260
+ }
250
261
  const keys = Object.keys(args);
251
262
  const newArgs: { [key: string]: any } = {};
252
263
  for (let key of keys) {
@@ -265,6 +276,11 @@ export const toJSONSchema = (route: RouteInfo) => {
265
276
  export const fromJSONSchema = (route: RouteInfo): RouteInfo => {
266
277
  const args = route?.metadata?.args;
267
278
  if (!args) return route;
279
+ if (args["$schema"] || (args.type === 'object' && args.properties && typeof args.properties === 'object')) {
280
+ // 可能是整个schema
281
+ route.metadata.args = z.fromJSONSchema(args);
282
+ return route;
283
+ }
268
284
  const keys = Object.keys(args);
269
285
  const newArgs: { [key: string]: any } = {};
270
286
  for (let key of keys) {