@evandu/super-pi 0.1.130 → 0.1.132
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 +18 -0
- package/agents/super-pi-documents/index.ts +92 -0
- package/agents/super-pi-feishu/index.ts +88 -0
- package/agents/super-pi-knowledge/index.ts +32 -1
- package/agents/super-pi-task/core.ts +217 -0
- package/agents/super-pi-task/index.ts +74 -1
- package/agents/super-pi-web/index.ts +32 -0
- package/assets/fonts/LICENSE +92 -0
- package/assets/fonts/NotoSansSC-Bold.otf +0 -0
- package/assets/fonts/NotoSansSC-Regular.otf +0 -0
- package/dist/client/.super-pi-client-sources.json +13 -10
- package/dist/client/assets/CodeMirrorEditor-ktyL2PcX.js +2 -0
- package/dist/client/assets/{dist-BKp4AWEJ.js → dist--igDAzRS.js} +1 -1
- package/dist/client/assets/{dist-BBW2SE_R.js → dist-60usx__o.js} +1 -1
- package/dist/client/assets/{dist-GkIV1LTX.js → dist-8pdzh6h1.js} +1 -1
- package/dist/client/assets/{dist-B2nPVdKh.js → dist-B8OZ-n_C.js} +1 -1
- package/dist/client/assets/{dist-BDygQgZD.js → dist-BAJCrbnX.js} +1 -1
- package/dist/client/assets/{dist-CiSGSVBZ.js → dist-BJi5HmH4.js} +1 -1
- package/dist/client/assets/{dist-CRzRB9k3.js → dist-BRjGckmQ.js} +1 -1
- package/dist/client/assets/{dist-Cxerc7Bb.js → dist-Bg9zLfex.js} +1 -1
- package/dist/client/assets/{dist-C90MPTnk.js → dist-BjZUYxLd.js} +1 -1
- package/dist/client/assets/{dist-DmAOqr0M.js → dist-Bv6P2Rcp.js} +1 -1
- package/dist/client/assets/{dist-BhJGK8-b.js → dist-C6iAHGvb.js} +1 -1
- package/dist/client/assets/{dist-Dq4-QFAJ.js → dist-CMscy2Nn.js} +1 -1
- package/dist/client/assets/{dist-Ur37340K.js → dist-CPLCQDqy.js} +1 -1
- package/dist/client/assets/{dist-DZnUERoW.js → dist-CgmISAMr.js} +1 -1
- package/dist/client/assets/{dist-CWYRjnj-.js → dist-CoszOk5k.js} +1 -1
- package/dist/client/assets/{dist-CMnvChDX.js → dist-Cu75NyQ0.js} +1 -1
- package/dist/client/assets/{dist-HdeIBl2J.js → dist-DNZMXYNq.js} +1 -1
- package/dist/client/assets/{dist-BykVFExd.js → dist-D_Zdnhm8.js} +1 -1
- package/dist/client/assets/{dist-ChszWGDv.js → dist-DvHghuGd.js} +1 -1
- package/dist/client/assets/{dist-CZ9I2JCd.js → dist-Hj_dWgPr.js} +1 -1
- package/dist/client/assets/{dist-B61RSa-K.js → dist-Zhdkfvng.js} +1 -1
- package/dist/client/assets/{dist-DB5M5fZG.js → dist-vsMBLoxV.js} +1 -1
- package/dist/client/assets/{index-D_c-CYAr.js → index-ChyemF2I.js} +23 -21
- package/dist/client/assets/{index-CXB6U5mz.css → index-D3MEG8uH.css} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/server/application/document-service.d.ts +68 -0
- package/dist/server/application/document-service.js +120 -0
- package/dist/server/application/feishu-service.d.ts +132 -0
- package/dist/server/application/feishu-service.js +264 -0
- package/dist/server/application/run-service.js +49 -7
- package/dist/server/application/scheduled-task-service.d.ts +164 -0
- package/dist/server/application/scheduled-task-service.js +350 -0
- package/dist/server/command-handler.d.ts +25 -1
- package/dist/server/command-handler.js +60 -1
- package/dist/server/documents.d.ts +152 -0
- package/dist/server/documents.js +998 -0
- package/dist/server/feishu-cli.d.ts +207 -0
- package/dist/server/feishu-cli.js +419 -0
- package/dist/server/file-changes.js +6 -4
- package/dist/server/files.d.ts +32 -0
- package/dist/server/files.js +31 -3
- package/dist/server/http-server.js +324 -2
- package/dist/server/index.js +41 -2
- package/dist/server/inline-thinking.d.ts +90 -0
- package/dist/server/inline-thinking.js +181 -0
- package/dist/server/knowledge.d.ts +24 -14
- package/dist/server/knowledge.js +57 -34
- package/dist/server/persistence/app-state-repository.d.ts +13 -1
- package/dist/server/persistence/sqlite-state-repository.js +3 -0
- package/dist/server/pi-session-pool.js +2 -1
- package/dist/server/pi-session.d.ts +4 -0
- package/dist/server/pi-session.js +14 -0
- package/dist/server/presentations/schema.d.ts +120 -0
- package/dist/server/presentations/schema.js +128 -0
- package/dist/server/runtime.d.ts +67 -0
- package/dist/server/runtime.js +204 -18
- package/dist/server/scheduled-tasks.d.ts +101 -0
- package/dist/server/scheduled-tasks.js +138 -0
- package/dist/server/server-context.d.ts +19 -0
- package/dist/server/store.d.ts +30 -0
- package/dist/server/store.js +81 -2
- package/dist/server/subagents.js +33 -6
- package/dist/server/task-tool.d.ts +18 -0
- package/dist/server/task-tool.js +18 -0
- package/dist/server/types.d.ts +56 -0
- package/dist/server/web.d.ts +24 -0
- package/dist/server/web.js +180 -0
- package/package.json +45 -6
- package/skills/presentation/SKILL.md +30 -0
- package/skills/presentation/references/data.md +10 -0
- package/skills/presentation/references/quality.md +12 -0
- package/skills/presentation/references/story.md +12 -0
- package/skills/presentation/references/templates-and-editing.md +11 -0
- package/skills/presentation/references/visual-system.md +10 -0
- package/dist/.super-pi-check-inputs.json +0 -4
- package/dist/client/assets/CodeMirrorEditor-BNVBZZSS.js +0 -2
|
@@ -13,6 +13,7 @@ export class CommandHandler {
|
|
|
13
13
|
catalogService;
|
|
14
14
|
rootDir;
|
|
15
15
|
providerService;
|
|
16
|
+
scheduledTaskService;
|
|
16
17
|
/**
|
|
17
18
|
* The built-in terminal service.
|
|
18
19
|
*
|
|
@@ -28,7 +29,15 @@ export class CommandHandler {
|
|
|
28
29
|
* Optional because the command handler is constructed by tests that do not care about providers,
|
|
29
30
|
* and a missing service has to say so rather than take the whole handler down.
|
|
30
31
|
*/
|
|
31
|
-
providerService
|
|
32
|
+
providerService,
|
|
33
|
+
/**
|
|
34
|
+
* The scheduled tasks, and the clock behind them.
|
|
35
|
+
*
|
|
36
|
+
* Optional because the handler is constructed by tests that have no clock to give it, and a missing
|
|
37
|
+
* service has to say so rather than take the whole handler down - the same rule `providerService`
|
|
38
|
+
* follows.
|
|
39
|
+
*/
|
|
40
|
+
scheduledTaskService) {
|
|
32
41
|
this.workspaceService = workspaceService;
|
|
33
42
|
this.conversationService = conversationService;
|
|
34
43
|
this.runService = runService;
|
|
@@ -36,6 +45,7 @@ export class CommandHandler {
|
|
|
36
45
|
this.catalogService = catalogService;
|
|
37
46
|
this.rootDir = rootDir;
|
|
38
47
|
this.providerService = providerService;
|
|
48
|
+
this.scheduledTaskService = scheduledTaskService;
|
|
39
49
|
this.terminalService = terminalService;
|
|
40
50
|
}
|
|
41
51
|
/**
|
|
@@ -295,6 +305,44 @@ export class CommandHandler {
|
|
|
295
305
|
this.runService.stopWorkflow(command.workflowId);
|
|
296
306
|
return;
|
|
297
307
|
}
|
|
308
|
+
// THE SCHEDULED TASKS, five commands over one list.
|
|
309
|
+
//
|
|
310
|
+
// They are all here rather than in a service of their own because they are all one verb applied to
|
|
311
|
+
// one collection: the service owns the schedule and the clock, and this is the routing table that
|
|
312
|
+
// says which of its methods a command reaches.
|
|
313
|
+
if (command.type === "scheduledTask.create") {
|
|
314
|
+
await this.requireScheduledTasks().create({
|
|
315
|
+
name: command.name,
|
|
316
|
+
prompt: command.prompt,
|
|
317
|
+
schedule: command.schedule,
|
|
318
|
+
workspaceId: command.workspaceId,
|
|
319
|
+
model: command.model,
|
|
320
|
+
agentId: command.agentId,
|
|
321
|
+
}, "user");
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
if (command.type === "scheduledTask.update") {
|
|
325
|
+
await this.requireScheduledTasks().update(command.id, {
|
|
326
|
+
name: command.name,
|
|
327
|
+
prompt: command.prompt,
|
|
328
|
+
schedule: command.schedule,
|
|
329
|
+
model: command.model,
|
|
330
|
+
agentId: command.agentId,
|
|
331
|
+
});
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
if (command.type === "scheduledTask.delete") {
|
|
335
|
+
await this.requireScheduledTasks().remove(command.id);
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
if (command.type === "scheduledTask.trigger") {
|
|
339
|
+
await this.requireScheduledTasks().trigger(command.id);
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
|
+
if (command.type === "scheduledTask.toggle") {
|
|
343
|
+
await this.requireScheduledTasks().setEnabled(command.id, command.enabled);
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
298
346
|
if (command.type === "extension.ui.answer") {
|
|
299
347
|
const answer = command.cancelled
|
|
300
348
|
? { cancelled: true }
|
|
@@ -396,4 +444,15 @@ export class CommandHandler {
|
|
|
396
444
|
}
|
|
397
445
|
throw new Error(`未知的命令类型:${JSON.stringify(command.type ?? null)}`);
|
|
398
446
|
}
|
|
447
|
+
/**
|
|
448
|
+
* The scheduled-task service, or a refusal.
|
|
449
|
+
*
|
|
450
|
+
* A refusal in the client's own words rather than a crash: the panel that sent the command shows
|
|
451
|
+
* the message, and a handler that threw a TypeError would show nothing but a failed operation.
|
|
452
|
+
*/
|
|
453
|
+
requireScheduledTasks() {
|
|
454
|
+
if (!this.scheduledTaskService)
|
|
455
|
+
throw new Error("定时任务功能在这个实例上没有启用。");
|
|
456
|
+
return this.scheduledTaskService;
|
|
457
|
+
}
|
|
399
458
|
}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* THE DOCUMENT PARSING LAYER.
|
|
3
|
+
*
|
|
4
|
+
* It turns the files a person actually has - PDFs, Word documents, spreadsheets - into text, and it
|
|
5
|
+
* turns text back into those files. Everything else in Super Pi - the knowledge base, the agent's
|
|
6
|
+
* document tool - goes through here, so the same file reads the same way in both places.
|
|
7
|
+
*
|
|
8
|
+
* WHY IT LIVES ON THE SERVER AND NOT IN A PI EXTENSION. A Pi extension runs inside Pi's process, and
|
|
9
|
+
* Pi's process resolves `node_modules` against PI's install, not against Super Pi's. The parsing
|
|
10
|
+
* libraries are Super Pi's dependencies, so an extension could not load them: the code would work in
|
|
11
|
+
* the dev checkout and fail in every installed layout, which is the exact failure mode
|
|
12
|
+
* `scripts/installed-layout.test.mjs` exists to catch. The server is also the only layer that holds
|
|
13
|
+
* both the workspace's absolute paths and the capability tokens, so the path guard and the
|
|
14
|
+
* credential check live in the same place as the parsing.
|
|
15
|
+
*
|
|
16
|
+
* WHY EVERY LIBRARY IS OPTIONAL. The knowledge base's vector layer is optional for the same reason:
|
|
17
|
+
* a missing package must degrade the FEATURE, not break the PANEL. A user who did not install
|
|
18
|
+
* pdfjs-dist should still be able to run Super Pi and read their Markdown; they should get a clear
|
|
19
|
+
* sentence about which package to install when they try to read a PDF.
|
|
20
|
+
*/
|
|
21
|
+
/**
|
|
22
|
+
* The document formats this layer understands, by file extension.
|
|
23
|
+
*
|
|
24
|
+
* `ppt` is READ-ONLY: the legacy binary format has no pure-JS writer, and generating a real
|
|
25
|
+
* PowerPoint 97 file means reimplementing a 1997 binary format. Reading it is a record walk; writing
|
|
26
|
+
* it is refused with a pointer to `.pptx`.
|
|
27
|
+
*/
|
|
28
|
+
export type DocumentFormat = "pdf" | "docx" | "xlsx" | "pptx" | "ppt";
|
|
29
|
+
/**
|
|
30
|
+
* The tools the agent sees.
|
|
31
|
+
*
|
|
32
|
+
* Duplicated as literals in `agents/super-pi-documents/index.ts`, the way `KNOWLEDGE_TOOL_NAME` is:
|
|
33
|
+
* the extension runs in Pi's process and cannot import from the server, and a name that exists in
|
|
34
|
+
* only one of the two places is a name one of them will get wrong.
|
|
35
|
+
*/
|
|
36
|
+
export declare const DOCUMENT_READ_TOOL_NAME = "document_read";
|
|
37
|
+
export declare const DOCUMENT_WRITE_TOOL_NAME = "document_write";
|
|
38
|
+
/** What a caller needs to know about a document after it has been read. */
|
|
39
|
+
export type ExtractResult = {
|
|
40
|
+
/** The extracted text. Empty only when the source genuinely had no text layer. */
|
|
41
|
+
text: string;
|
|
42
|
+
/** The format the text came from. */
|
|
43
|
+
format: DocumentFormat;
|
|
44
|
+
/** How many pages the document had, when the format has pages. */
|
|
45
|
+
pages?: number;
|
|
46
|
+
/**
|
|
47
|
+
* What was lost in the conversion, stated rather than hidden.
|
|
48
|
+
*
|
|
49
|
+
* WHY THIS IS A FIELD AND NOT A LOG LINE. A Word document's tables become pipe-separated lines and
|
|
50
|
+
* its images become nothing at all. A caller that knows the extraction was lossy can say so to the
|
|
51
|
+
* person; a caller that does not will present a flattened table as if it were the document.
|
|
52
|
+
*/
|
|
53
|
+
warnings: string[];
|
|
54
|
+
};
|
|
55
|
+
/** The failure of a document that could not be read, in a form a person can act on. */
|
|
56
|
+
export declare class DocumentError extends Error {
|
|
57
|
+
readonly code: DocumentErrorCode;
|
|
58
|
+
constructor(code: DocumentErrorCode, message: string);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* WHY THE CODES EXIST. "Read failed" is not actionable, and the ways a document fails are
|
|
62
|
+
* genuinely different from one another: a dependency is missing (install something), a PDF has no
|
|
63
|
+
* text layer (it is a scan - use a different route), a PDF is encrypted (it needs a password), and
|
|
64
|
+
* the file is simply broken (nothing to do about it). Each of those needs a different sentence, and
|
|
65
|
+
* a person who is told "read failed" learns nothing.
|
|
66
|
+
*/
|
|
67
|
+
export type DocumentErrorCode = "missing_dependency" | "missing_asset" | "no_text_layer" | "encrypted" | "corrupt" | "unsupported" | "empty";
|
|
68
|
+
/**
|
|
69
|
+
* Whether an extension names a document this layer can read.
|
|
70
|
+
*
|
|
71
|
+
* The name is checked BEFORE the bytes are sniffed, because the caller needs to know whether to
|
|
72
|
+
* attempt a parse at all - and because a `.pdf` that is really a text file is a different situation
|
|
73
|
+
* from a file with no extension that happens to be a PDF.
|
|
74
|
+
*/
|
|
75
|
+
export declare function isDocumentFormat(extension: string): boolean;
|
|
76
|
+
/** The format an extension names, or null when it names none. */
|
|
77
|
+
export declare function documentFormatOf(extension: string): DocumentFormat | null;
|
|
78
|
+
/** The extension a format is written with. */
|
|
79
|
+
export declare function extensionForFormat(format: DocumentFormat): string;
|
|
80
|
+
/**
|
|
81
|
+
* Reads a document's text.
|
|
82
|
+
*
|
|
83
|
+
* The file is read here rather than handed in as a buffer because the parsers differ in what they
|
|
84
|
+
* want: pdfjs wants a path or a typed array, mammoth wants a buffer, exceljs wants a stream or a
|
|
85
|
+
* buffer. Reading once here keeps that difference from leaking into the callers.
|
|
86
|
+
*/
|
|
87
|
+
export declare function extractText(path: string, format: DocumentFormat): Promise<ExtractResult>;
|
|
88
|
+
/**
|
|
89
|
+
* Reads a document's text from bytes already in hand.
|
|
90
|
+
*
|
|
91
|
+
* Split out from `extractText` so the parsers can be exercised without touching the filesystem, and
|
|
92
|
+
* so a caller that already has the bytes (an upload, an API request) does not write them to a
|
|
93
|
+
* temporary file to read them back.
|
|
94
|
+
*/
|
|
95
|
+
export declare function extractTextFromBytes(bytes: Buffer, format: DocumentFormat): Promise<ExtractResult>;
|
|
96
|
+
/**
|
|
97
|
+
* WHAT A DOCUMENT IS TO BE WRITTEN FROM.
|
|
98
|
+
*
|
|
99
|
+
* The content is Markdown for prose documents and CSV for spreadsheets, chosen by the format rather
|
|
100
|
+
* than by the caller: a spreadsheet built from Markdown is a table with the wrong shape, and the
|
|
101
|
+
* caller should not have to know that.
|
|
102
|
+
*/
|
|
103
|
+
export type DocumentSpec = {
|
|
104
|
+
format: DocumentFormat;
|
|
105
|
+
/** The content. Markdown for `docx`, `pdf` and `pptx`, CSV for `xlsx`. */
|
|
106
|
+
content: string;
|
|
107
|
+
/** The document's title, used for the Word heading and the PDF title line. */
|
|
108
|
+
title?: string;
|
|
109
|
+
};
|
|
110
|
+
/**
|
|
111
|
+
* Builds a document's bytes.
|
|
112
|
+
*
|
|
113
|
+
* The output is a REAL document - it opens in Word, Excel and a PDF reader - not a renamed text
|
|
114
|
+
* file. The structure is simple on purpose: headings, paragraphs, lists and tables for Word;
|
|
115
|
+
* sheets of cells for Excel; lines of text for a PDF.
|
|
116
|
+
*/
|
|
117
|
+
export declare function buildDocument(spec: DocumentSpec): Promise<{
|
|
118
|
+
bytes: Buffer;
|
|
119
|
+
format: DocumentFormat;
|
|
120
|
+
}>;
|
|
121
|
+
/**
|
|
122
|
+
* The blocks a Markdown document is made of.
|
|
123
|
+
*
|
|
124
|
+
* A full Markdown parser is not needed here, and pulling one in would mean deciding what to do with
|
|
125
|
+
* the constructs it supports that a Word document has no place for. The subset below is the one a
|
|
126
|
+
* person actually uses when they ask for "a Word version of this".
|
|
127
|
+
*/
|
|
128
|
+
type Block = {
|
|
129
|
+
kind: "heading";
|
|
130
|
+
level: number;
|
|
131
|
+
text: string;
|
|
132
|
+
} | {
|
|
133
|
+
kind: "paragraph";
|
|
134
|
+
text: string;
|
|
135
|
+
} | {
|
|
136
|
+
kind: "list";
|
|
137
|
+
items: string[];
|
|
138
|
+
} | {
|
|
139
|
+
kind: "table";
|
|
140
|
+
header: string[];
|
|
141
|
+
rows: string[][];
|
|
142
|
+
} | {
|
|
143
|
+
kind: "code";
|
|
144
|
+
text: string;
|
|
145
|
+
};
|
|
146
|
+
/** Splits Markdown into the blocks a document is built from. Exported for the tests to exercise directly. */
|
|
147
|
+
export declare function parseMarkdownBlocks(markdown: string): Block[];
|
|
148
|
+
/**
|
|
149
|
+
* The format a file's extension names, for the callers that hold a path rather than a format.
|
|
150
|
+
*/
|
|
151
|
+
export declare function formatOfPath(path: string): DocumentFormat | null;
|
|
152
|
+
export {};
|