pi-provider-kimi-code 0.6.13 → 0.6.14

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,5 +1,12 @@
1
1
  import { defineTool } from "@earendil-works/pi-coding-agent";
2
- import { Type, type Static } from "@earendil-works/pi-ai";
2
+ import { map, obj, opt, str, unknown, type Static } from "@earendil-works/pi-schema";
3
+
4
+ import {
5
+ ensureDatasourceCatalog,
6
+ peekDatasourceCatalog,
7
+ readCatalogCacheSync,
8
+ refreshDatasourceCatalogInBackground,
9
+ } from "./datasource-catalog.ts";
3
10
 
4
11
  import {
5
12
  type BuildKimiToolOptions,
@@ -15,72 +22,21 @@ import {
15
22
  textComponent,
16
23
  } from "./common.ts";
17
24
 
18
- const DATASOURCE_DEFINITIONS = [
19
- {
20
- name: "stock_finance_data",
21
- description: "A/HK/US stocks, prices, financial reports, indicators, shareholders.",
22
- },
23
- {
24
- name: "yahoo_finance",
25
- description: "Global finance: quotes, analyst ratings, options, indexes, historical prices.",
26
- },
27
- {
28
- name: "world_bank_open_data",
29
- description: "World Bank macro data: GDP, inflation, population, country comparisons.",
30
- },
31
- {
32
- name: "tianyancha",
33
- description: "Chinese enterprise registry: shareholders, legal representative, risks, patents.",
34
- },
35
- { name: "arxiv", description: "arXiv preprints: paper search, abstracts, arXiv IDs." },
36
- {
37
- name: "scholar",
38
- description: "Google Scholar: academic papers, authors, citations, high-citation surveys.",
39
- },
40
- {
41
- name: "yuandian_law",
42
- description: "Chinese laws, regulations, judicial cases; labor contracts and legal clauses.",
43
- },
44
- {
45
- name: "wind",
25
+ // Source names are validated at call time against the synced catalog
26
+ // (datasource-catalog.ts) instead of a static enum, so sources added
27
+ // server-side never get rejected by a stale client schema.
28
+ export const kimiDatasourceSchema = obj({
29
+ data_source_name: str({
46
30
  description:
47
- "A-share intraday minute series, funds, bonds; map PE/PB/ROE-style field names via wind_search_fields first.",
48
- },
49
- {
50
- name: "imf",
51
- description: "IMF macro data: FX rates, CPI, GDP forecasts, balance of payments.",
52
- },
53
- {
54
- name: "gildata",
55
- description: "Natural-language stock/fund screening.",
56
- },
57
- {
58
- name: "sec_edgar",
59
- description: "US SEC filings: 10-K/10-Q, S-1, Form 4, 13F, 8-K.",
60
- },
61
- {
62
- name: "sp_data",
63
- description: "S&P fundamentals: consensus estimates, valuation ratios, transcripts.",
64
- },
65
- ] as const;
66
-
67
- const DATASOURCE_NAMES = DATASOURCE_DEFINITIONS.map((source) => source.name);
68
-
69
- export const kimiDatasourceSchema = Type.Object({
70
- data_source_name: Type.Union(
71
- DATASOURCE_NAMES.map((name) => Type.Literal(name)),
72
- {
73
- description:
74
- "Source: stock_finance_data stocks/reports; yahoo_finance quotes/options; world_bank_open_data GDP/population; imf FX/CPI/GDP forecasts; tianyancha Chinese company registry/legal rep; arxiv preprints; scholar citations; yuandian_law Chinese laws/cases/contracts; wind A-share intraday minute series/funds/bonds (map field names via wind_search_fields first); gildata natural-language stock/fund screening; sec_edgar US filings (10-K/10-Q, S-1, Form 4, 13F, 8-K); sp_data S&P fundamentals (estimates, valuation, transcripts).",
75
- },
76
- ),
77
- api_name: Type.Optional(
78
- Type.String({
31
+ "Data source name. The set of available sources is synced from the official kimi-datasource plugin and cached for 24h; if a call fails with an unknown-source error, pick one of the names listed in that error.",
32
+ }),
33
+ api_name: opt(
34
+ str({
79
35
  description: "API name from the datasource docs. Omit to get docs first.",
80
36
  }),
81
37
  ),
82
- params: Type.Optional(
83
- Type.Record(Type.String(), Type.Unknown(), {
38
+ params: opt(
39
+ map(unknown(), {
84
40
  description: "Parameters matching the selected datasource API docs.",
85
41
  }),
86
42
  ),
@@ -164,6 +120,16 @@ function buildTraceLine(toolCallId: string, requestId: string | undefined): stri
164
120
  return `\n\n[kimi-datasource] ${parts.join(" · ")}`;
165
121
  }
166
122
 
123
+ function buildDescription(): string {
124
+ const base =
125
+ "Call Kimi datasource APIs: finance/quotes, macro & government data, papers, Chinese law, chemistry/bio/materials, and more. First omit api_name to get docs, then call api_name with documented params.";
126
+ // Registration-time snapshot: embed the cached catalog so the model sees the
127
+ // current source list without any network I/O. Refreshed lazily on use.
128
+ const cached = readCatalogCacheSync();
129
+ if (!cached) return base;
130
+ return `${base} Known sources (kimi-datasource v${cached.version}): ${cached.capabilities}`;
131
+ }
132
+
167
133
  export function buildKimiDatasourceTool(options: BuildKimiToolOptions = {}) {
168
134
  const deps = buildKimiToolDeps(options);
169
135
  const defaultCollapsed = options.defaultCollapsed ?? true;
@@ -171,12 +137,11 @@ export function buildKimiDatasourceTool(options: BuildKimiToolOptions = {}) {
171
137
  return defineTool({
172
138
  name: "kimi_datasource",
173
139
  label: "Kimi Datasource",
174
- description:
175
- "Call Kimi datasource APIs. Covers stocks/finance, macro data, Chinese company registry, papers, and Chinese law/cases/contracts. First omit api_name to get docs, then call api_name with documented params.",
140
+ description: buildDescription(),
176
141
  promptSnippet: "Query Kimi datasource APIs; get docs first, then call documented api_name",
177
142
  parameters: kimiDatasourceSchema,
178
143
 
179
- async execute(toolCallId, params, signal) {
144
+ async execute(toolCallId, params: KimiDatasourceParams, signal) {
180
145
  const accessToken = deps.getAccessToken();
181
146
  if (!accessToken) {
182
147
  return errorResult<string>(
@@ -186,19 +151,40 @@ export function buildKimiDatasourceTool(options: BuildKimiToolOptions = {}) {
186
151
 
187
152
  const timeout = buildTimeoutSignal(signal);
188
153
  try {
154
+ const sourceName = params.data_source_name.trim();
155
+
156
+ // Lazy catalog sync: validate against the best-known catalog without
157
+ // blocking, and refresh in the background when it is stale. Unknown
158
+ // names get one forced refresh before we reject them, so newly added
159
+ // server-side sources work even when the local cache is old.
160
+ let catalog = peekDatasourceCatalog();
161
+ if (!catalog.sources.includes(sourceName)) {
162
+ catalog = await ensureDatasourceCatalog({
163
+ fetchImpl: deps.fetch,
164
+ forceRefresh: true,
165
+ });
166
+ if (!catalog.sources.includes(sourceName)) {
167
+ return errorResult<string>(
168
+ `Unknown data source "${sourceName}". Available sources (kimi-datasource v${catalog.version}): ${catalog.sources.join(", ")}`,
169
+ );
170
+ }
171
+ } else {
172
+ refreshDatasourceCatalogInBackground(deps.fetch);
173
+ }
174
+
189
175
  const apiName = params.api_name?.trim();
190
176
  const body = apiName
191
177
  ? {
192
178
  method: "call_data_source_tool",
193
179
  params: {
194
- data_source_name: params.data_source_name,
180
+ data_source_name: sourceName,
195
181
  api_name: apiName,
196
182
  params: params.params ?? {},
197
183
  },
198
184
  }
199
185
  : {
200
186
  method: "get_data_source_desc",
201
- params: { name: params.data_source_name },
187
+ params: { name: sourceName },
202
188
  };
203
189
 
204
190
  const response = await fetchWithAuthRetry(deps, accessToken, (token) =>
@@ -1,5 +1,5 @@
1
1
  import { defineTool, type AgentToolResult } from "@earendil-works/pi-coding-agent";
2
- import { Type, type Static } from "@earendil-works/pi-ai";
2
+ import { obj, str, type Static } from "@earendil-works/pi-schema";
3
3
 
4
4
  import {
5
5
  type BuildKimiToolOptions,
@@ -15,12 +15,12 @@ import {
15
15
  textComponent,
16
16
  } from "./common.ts";
17
17
 
18
- export const moonshotSearchSchema = Type.Object({
19
- query: Type.String({ description: "The query text to search for." }),
18
+ export const moonshotSearchSchema = obj({
19
+ query: str({ description: "The query text to search for." }),
20
20
  });
21
21
 
22
- export const moonshotFetchSchema = Type.Object({
23
- url: Type.String({ description: "The URL to fetch content from." }),
22
+ export const moonshotFetchSchema = obj({
23
+ url: str({ description: "The URL to fetch content from." }),
24
24
  });
25
25
 
26
26
  export type MoonshotSearchParams = Static<typeof moonshotSearchSchema>;
@@ -119,7 +119,7 @@ export function buildMoonshotSearchTool(options: BuildKimiToolOptions = {}) {
119
119
  "Search the web with Kimi Coding, then fetch the few relevant result URLs before answering",
120
120
  parameters: moonshotSearchSchema,
121
121
 
122
- async execute(toolCallId, params, signal) {
122
+ async execute(toolCallId, params: MoonshotSearchParams, signal) {
123
123
  const accessToken = deps.getAccessToken();
124
124
  if (!accessToken) {
125
125
  return errorResult<MoonshotSearchResult[]>(
@@ -176,7 +176,7 @@ export function buildMoonshotFetchTool(options: BuildKimiToolOptions = {}) {
176
176
  promptSnippet: "Fetch a web page with Kimi Coding's Moonshot fetch service",
177
177
  parameters: moonshotFetchSchema,
178
178
 
179
- async execute(toolCallId, params, signal) {
179
+ async execute(toolCallId, params: MoonshotFetchParams, signal) {
180
180
  const accessToken = deps.getAccessToken();
181
181
  if (!accessToken) {
182
182
  return errorResult<MoonshotFetchResult>(