plugin-agent-orchestrator 1.0.6 → 1.0.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.
- package/README.md +16 -291
- package/dist/client/AIEmployeesContext.d.ts +7 -0
- package/dist/client/OrchestratorSettings.d.ts +2 -1
- package/dist/client/index.js +1 -1
- package/dist/client/plugin.d.ts +1 -0
- package/dist/client/skill-hub/components/ExecutionHistory.d.ts +2 -0
- package/dist/client/skill-hub/components/ExecutionProgress.d.ts +20 -0
- package/dist/client/skill-hub/components/GitSkillImport.d.ts +7 -0
- package/dist/client/skill-hub/components/SkillEditor.d.ts +7 -0
- package/dist/client/skill-hub/components/SkillManager.d.ts +2 -0
- package/dist/client/skill-hub/components/SkillMetrics.d.ts +2 -0
- package/dist/client/skill-hub/components/SkillTestPanel.d.ts +7 -0
- package/dist/client/skill-hub/index.d.ts +10 -0
- package/dist/client/skill-hub/locale.d.ts +3 -0
- package/dist/client/skill-hub/tools/InteractionSchemasProvider.d.ts +19 -0
- package/dist/client/skill-hub/tools/SkillHubCard.d.ts +3 -0
- package/dist/client/skill-hub/utils/jsonFields.d.ts +3 -0
- package/dist/externalVersion.js +6 -6
- package/dist/node_modules/adm-zip/LICENSE +21 -0
- package/dist/node_modules/adm-zip/adm-zip.js +1 -0
- package/dist/node_modules/adm-zip/headers/entryHeader.js +377 -0
- package/dist/node_modules/adm-zip/headers/index.js +2 -0
- package/dist/node_modules/adm-zip/headers/mainHeader.js +130 -0
- package/dist/node_modules/adm-zip/methods/deflater.js +33 -0
- package/dist/node_modules/adm-zip/methods/index.js +3 -0
- package/dist/node_modules/adm-zip/methods/inflater.js +34 -0
- package/dist/node_modules/adm-zip/methods/zipcrypto.js +175 -0
- package/dist/node_modules/adm-zip/package.json +1 -0
- package/dist/node_modules/adm-zip/util/constants.js +142 -0
- package/dist/node_modules/adm-zip/util/decoder.js +5 -0
- package/dist/node_modules/adm-zip/util/errors.js +63 -0
- package/dist/node_modules/adm-zip/util/fattr.js +76 -0
- package/dist/node_modules/adm-zip/util/index.js +5 -0
- package/dist/node_modules/adm-zip/util/utils.js +339 -0
- package/dist/node_modules/adm-zip/zipEntry.js +405 -0
- package/dist/node_modules/adm-zip/zipFile.js +446 -0
- package/dist/node_modules/simple-git/dist/cjs/index.js +7399 -0
- package/dist/node_modules/simple-git/dist/esm/index.js +4745 -0
- package/dist/node_modules/simple-git/dist/esm/package.json +3 -0
- package/dist/node_modules/simple-git/dist/src/lib/api.d.ts +13 -0
- package/dist/node_modules/simple-git/dist/src/lib/args/log-format.d.ts +9 -0
- package/dist/node_modules/simple-git/dist/src/lib/errors/git-construct-error.d.ts +15 -0
- package/dist/node_modules/simple-git/dist/src/lib/errors/git-error.d.ts +30 -0
- package/dist/node_modules/simple-git/dist/src/lib/errors/git-plugin-error.d.ts +7 -0
- package/dist/node_modules/simple-git/dist/src/lib/errors/git-response-error.d.ts +32 -0
- package/dist/node_modules/simple-git/dist/src/lib/errors/task-configuration-error.d.ts +12 -0
- package/dist/node_modules/simple-git/dist/src/lib/git-factory.d.ts +15 -0
- package/dist/node_modules/simple-git/dist/src/lib/git-logger.d.ts +21 -0
- package/dist/node_modules/simple-git/dist/src/lib/parsers/parse-branch-delete.d.ts +5 -0
- package/dist/node_modules/simple-git/dist/src/lib/parsers/parse-branch.d.ts +2 -0
- package/dist/node_modules/simple-git/dist/src/lib/parsers/parse-commit.d.ts +2 -0
- package/dist/node_modules/simple-git/dist/src/lib/parsers/parse-diff-summary.d.ts +3 -0
- package/dist/node_modules/simple-git/dist/src/lib/parsers/parse-fetch.d.ts +2 -0
- package/dist/node_modules/simple-git/dist/src/lib/parsers/parse-list-log-summary.d.ts +6 -0
- package/dist/node_modules/simple-git/dist/src/lib/parsers/parse-merge.d.ts +11 -0
- package/dist/node_modules/simple-git/dist/src/lib/parsers/parse-move.d.ts +2 -0
- package/dist/node_modules/simple-git/dist/src/lib/parsers/parse-pull.d.ts +6 -0
- package/dist/node_modules/simple-git/dist/src/lib/parsers/parse-push.d.ts +4 -0
- package/dist/node_modules/simple-git/dist/src/lib/parsers/parse-remote-messages.d.ts +5 -0
- package/dist/node_modules/simple-git/dist/src/lib/parsers/parse-remote-objects.d.ts +3 -0
- package/dist/node_modules/simple-git/dist/src/lib/plugins/abort-plugin.d.ts +3 -0
- package/dist/node_modules/simple-git/dist/src/lib/plugins/block-unsafe-operations-plugin.d.ts +3 -0
- package/dist/node_modules/simple-git/dist/src/lib/plugins/command-config-prefixing-plugin.d.ts +2 -0
- package/dist/node_modules/simple-git/dist/src/lib/plugins/completion-detection.plugin.d.ts +3 -0
- package/dist/node_modules/simple-git/dist/src/lib/plugins/custom-binary.plugin.d.ts +3 -0
- package/dist/node_modules/simple-git/dist/src/lib/plugins/error-detection.plugin.d.ts +7 -0
- package/dist/node_modules/simple-git/dist/src/lib/plugins/index.d.ts +11 -0
- package/dist/node_modules/simple-git/dist/src/lib/plugins/plugin-store.d.ts +11 -0
- package/dist/node_modules/simple-git/dist/src/lib/plugins/progress-monitor-plugin.d.ts +3 -0
- package/dist/node_modules/simple-git/dist/src/lib/plugins/simple-git-plugin.d.ts +48 -0
- package/dist/node_modules/simple-git/dist/src/lib/plugins/spawn-options-plugin.d.ts +3 -0
- package/dist/node_modules/simple-git/dist/src/lib/plugins/suffix-paths.plugin.d.ts +2 -0
- package/dist/node_modules/simple-git/dist/src/lib/plugins/timout-plugin.d.ts +3 -0
- package/dist/node_modules/simple-git/dist/src/lib/responses/BranchDeleteSummary.d.ts +12 -0
- package/dist/node_modules/simple-git/dist/src/lib/responses/BranchSummary.d.ts +14 -0
- package/dist/node_modules/simple-git/dist/src/lib/responses/CheckIgnore.d.ts +4 -0
- package/dist/node_modules/simple-git/dist/src/lib/responses/CleanSummary.d.ts +9 -0
- package/dist/node_modules/simple-git/dist/src/lib/responses/ConfigList.d.ts +13 -0
- package/dist/node_modules/simple-git/dist/src/lib/responses/DiffSummary.d.ts +10 -0
- package/dist/node_modules/simple-git/dist/src/lib/responses/FileStatusSummary.d.ts +9 -0
- package/dist/node_modules/simple-git/dist/src/lib/responses/GetRemoteSummary.d.ts +11 -0
- package/dist/node_modules/simple-git/dist/src/lib/responses/InitSummary.d.ts +9 -0
- package/dist/node_modules/simple-git/dist/src/lib/responses/MergeSummary.d.ts +16 -0
- package/dist/node_modules/simple-git/dist/src/lib/responses/PullSummary.d.ts +25 -0
- package/dist/node_modules/simple-git/dist/src/lib/responses/StatusSummary.d.ts +19 -0
- package/dist/node_modules/simple-git/dist/src/lib/responses/TagList.d.ts +7 -0
- package/dist/node_modules/simple-git/dist/src/lib/runners/git-executor-chain.d.ts +25 -0
- package/dist/node_modules/simple-git/dist/src/lib/runners/git-executor.d.ts +14 -0
- package/dist/node_modules/simple-git/dist/src/lib/runners/promise-wrapped.d.ts +2 -0
- package/dist/node_modules/simple-git/dist/src/lib/runners/scheduler.d.ts +11 -0
- package/dist/node_modules/simple-git/dist/src/lib/runners/tasks-pending-queue.d.ts +23 -0
- package/dist/node_modules/simple-git/dist/src/lib/simple-git-api.d.ts +20 -0
- package/dist/node_modules/simple-git/dist/src/lib/task-callback.d.ts +2 -0
- package/dist/node_modules/simple-git/dist/src/lib/tasks/apply-patch.d.ts +3 -0
- package/dist/node_modules/simple-git/dist/src/lib/tasks/branch.d.ts +7 -0
- package/dist/node_modules/simple-git/dist/src/lib/tasks/change-working-directory.d.ts +2 -0
- package/dist/node_modules/simple-git/dist/src/lib/tasks/check-ignore.d.ts +2 -0
- package/dist/node_modules/simple-git/dist/src/lib/tasks/check-is-repo.d.ts +9 -0
- package/dist/node_modules/simple-git/dist/src/lib/tasks/checkout.d.ts +2 -0
- package/dist/node_modules/simple-git/dist/src/lib/tasks/clean.d.ts +25 -0
- package/dist/node_modules/simple-git/dist/src/lib/tasks/clone.d.ts +9 -0
- package/dist/node_modules/simple-git/dist/src/lib/tasks/commit.d.ts +4 -0
- package/dist/node_modules/simple-git/dist/src/lib/tasks/config.d.ts +8 -0
- package/dist/node_modules/simple-git/dist/src/lib/tasks/count-objects.d.ts +12 -0
- package/dist/node_modules/simple-git/dist/src/lib/tasks/diff-name-status.d.ts +12 -0
- package/dist/node_modules/simple-git/dist/src/lib/tasks/diff.d.ts +5 -0
- package/dist/node_modules/simple-git/dist/src/lib/tasks/fetch.d.ts +4 -0
- package/dist/node_modules/simple-git/dist/src/lib/tasks/first-commit.d.ts +2 -0
- package/dist/node_modules/simple-git/dist/src/lib/tasks/grep.d.ts +12 -0
- package/dist/node_modules/simple-git/dist/src/lib/tasks/hash-object.d.ts +5 -0
- package/dist/node_modules/simple-git/dist/src/lib/tasks/init.d.ts +3 -0
- package/dist/node_modules/simple-git/dist/src/lib/tasks/log.d.ts +32 -0
- package/dist/node_modules/simple-git/dist/src/lib/tasks/merge.d.ts +4 -0
- package/dist/node_modules/simple-git/dist/src/lib/tasks/move.d.ts +3 -0
- package/dist/node_modules/simple-git/dist/src/lib/tasks/pull.d.ts +3 -0
- package/dist/node_modules/simple-git/dist/src/lib/tasks/push.d.ts +9 -0
- package/dist/node_modules/simple-git/dist/src/lib/tasks/remote.d.ts +8 -0
- package/dist/node_modules/simple-git/dist/src/lib/tasks/reset.d.ts +11 -0
- package/dist/node_modules/simple-git/dist/src/lib/tasks/show.d.ts +2 -0
- package/dist/node_modules/simple-git/dist/src/lib/tasks/stash-list.d.ts +4 -0
- package/dist/node_modules/simple-git/dist/src/lib/tasks/status.d.ts +3 -0
- package/dist/node_modules/simple-git/dist/src/lib/tasks/sub-module.d.ts +5 -0
- package/dist/node_modules/simple-git/dist/src/lib/tasks/tag.d.ts +18 -0
- package/dist/node_modules/simple-git/dist/src/lib/tasks/task.d.ts +14 -0
- package/dist/node_modules/simple-git/dist/src/lib/tasks/version.d.ts +9 -0
- package/dist/node_modules/simple-git/dist/src/lib/types/handlers.d.ts +21 -0
- package/dist/node_modules/simple-git/dist/src/lib/types/index.d.ts +136 -0
- package/dist/node_modules/simple-git/dist/src/lib/types/tasks.d.ts +19 -0
- package/dist/node_modules/simple-git/dist/src/lib/utils/argument-filters.d.ts +14 -0
- package/dist/node_modules/simple-git/dist/src/lib/utils/exit-codes.d.ts +10 -0
- package/dist/node_modules/simple-git/dist/src/lib/utils/git-output-streams.d.ts +7 -0
- package/dist/node_modules/simple-git/dist/src/lib/utils/index.d.ts +8 -0
- package/dist/node_modules/simple-git/dist/src/lib/utils/line-parser.d.ts +15 -0
- package/dist/node_modules/simple-git/dist/src/lib/utils/simple-git-options.d.ts +2 -0
- package/dist/node_modules/simple-git/dist/src/lib/utils/task-options.d.ts +13 -0
- package/dist/node_modules/simple-git/dist/src/lib/utils/task-parser.d.ts +5 -0
- package/dist/node_modules/simple-git/dist/src/lib/utils/util.d.ts +47 -0
- package/dist/node_modules/simple-git/dist/typings/errors.d.ts +5 -0
- package/dist/node_modules/simple-git/dist/typings/index.d.ts +14 -0
- package/dist/node_modules/simple-git/dist/typings/response.d.ts +556 -0
- package/dist/node_modules/simple-git/dist/typings/simple-git.d.ts +1033 -0
- package/dist/node_modules/simple-git/dist/typings/types.d.ts +22 -0
- package/dist/node_modules/simple-git/node_modules/debug/package.json +64 -0
- package/dist/node_modules/simple-git/node_modules/debug/src/browser.js +272 -0
- package/dist/node_modules/simple-git/node_modules/debug/src/common.js +292 -0
- package/dist/node_modules/simple-git/node_modules/debug/src/index.js +10 -0
- package/dist/node_modules/simple-git/node_modules/debug/src/node.js +263 -0
- package/dist/node_modules/simple-git/package.json +1 -0
- package/dist/node_modules/simple-git/promise.js +17 -0
- package/dist/server/collections/agent-execution-spans.d.ts +9 -0
- package/dist/server/collections/agent-execution-spans.js +152 -0
- package/dist/server/collections/orchestrator-config.js +16 -0
- package/dist/server/collections/orchestrator-logs.js +19 -2
- package/dist/server/collections/skill-definitions.d.ts +3 -0
- package/dist/server/collections/skill-definitions.js +158 -0
- package/dist/server/collections/skill-executions.d.ts +3 -0
- package/dist/server/collections/skill-executions.js +123 -0
- package/dist/server/collections/skill-worker-configs.d.ts +3 -0
- package/dist/server/collections/skill-worker-configs.js +115 -0
- package/dist/server/migrations/20260423000000-add-progress-fields.d.ts +4 -0
- package/dist/server/migrations/20260423000000-add-progress-fields.js +69 -0
- package/dist/server/migrations/20260425000000-add-interaction-schema.d.ts +4 -0
- package/dist/server/migrations/20260425000000-add-interaction-schema.js +61 -0
- package/dist/server/migrations/20260427000000-add-tracing-detail-fields.d.ts +7 -0
- package/dist/server/migrations/20260427000000-add-tracing-detail-fields.js +62 -0
- package/dist/server/migrations/20260427000000-change-packages-to-text.d.ts +4 -0
- package/dist/server/migrations/20260427000000-change-packages-to-text.js +70 -0
- package/dist/server/migrations/20260427000001-change-other-json-to-text.d.ts +4 -0
- package/dist/server/migrations/20260427000001-change-other-json-to-text.js +80 -0
- package/dist/server/migrations/20260429000000-add-llm-fields.d.ts +7 -0
- package/dist/server/migrations/20260429000000-add-llm-fields.js +68 -0
- package/dist/server/migrations/20260429000000-fix-inputargs-json-to-text.d.ts +16 -0
- package/dist/server/migrations/20260429000000-fix-inputargs-json-to-text.js +51 -0
- package/dist/server/migrations/20260503000000-add-orchestrator-trace-fields.d.ts +7 -0
- package/dist/server/migrations/20260503000000-add-orchestrator-trace-fields.js +57 -0
- package/dist/server/plugin.d.ts +3 -0
- package/dist/server/plugin.js +37 -1
- package/dist/server/resources/tracing.js +160 -12
- package/dist/server/services/CodeValidator.d.ts +32 -0
- package/dist/server/services/CodeValidator.js +205 -0
- package/dist/server/services/ExecutionSpanService.d.ts +44 -0
- package/dist/server/services/ExecutionSpanService.js +104 -0
- package/dist/server/services/FileManager.d.ts +28 -0
- package/dist/server/services/FileManager.js +151 -0
- package/dist/server/services/SandboxRunner.d.ts +41 -0
- package/dist/server/services/SandboxRunner.js +167 -0
- package/dist/server/services/SkillManager.d.ts +6 -0
- package/dist/server/services/SkillManager.js +640 -0
- package/dist/server/services/SkillRepositoryService.d.ts +22 -0
- package/dist/server/services/SkillRepositoryService.js +157 -0
- package/dist/server/services/WorkerEnvManager.d.ts +26 -0
- package/dist/server/services/WorkerEnvManager.js +120 -0
- package/dist/server/skill-hub/actions/git-import.d.ts +21 -0
- package/dist/server/skill-hub/actions/git-import.js +413 -0
- package/dist/server/skill-hub/mcp/McpController.d.ts +15 -0
- package/dist/server/skill-hub/mcp/McpController.js +111 -0
- package/dist/server/skill-hub/plugin.d.ts +58 -0
- package/dist/server/skill-hub/plugin.js +694 -0
- package/dist/server/skill-hub/sandbox-config.json +6 -0
- package/dist/server/skill-hub/tasks/SkillExecutionTask.d.ts +14 -0
- package/dist/server/skill-hub/tasks/SkillExecutionTask.js +267 -0
- package/dist/server/skill-hub/utils/json-fields.d.ts +7 -0
- package/dist/server/skill-hub/utils/json-fields.js +88 -0
- package/dist/server/tools/delegate-task.d.ts +4 -0
- package/dist/server/tools/delegate-task.js +832 -119
- package/dist/server/tools/skill-execute.d.ts +36 -0
- package/dist/server/tools/skill-execute.js +167 -0
- package/package.json +3 -1
- package/src/client/AIEmployeeSelect.tsx +1 -3
- package/src/client/AIEmployeesContext.tsx +28 -13
- package/src/client/OrchestratorSettings.tsx +43 -5
- package/src/client/RulesTab.tsx +368 -21
- package/src/client/TracingTab.tsx +316 -102
- package/src/client/plugin.tsx +39 -0
- package/src/client/skill-hub/components/ExecutionHistory.tsx +201 -0
- package/src/client/skill-hub/components/ExecutionProgress.tsx +55 -0
- package/src/client/skill-hub/components/GitSkillImport.tsx +555 -0
- package/src/client/skill-hub/components/SkillEditor.tsx +456 -0
- package/src/client/skill-hub/components/SkillManager.tsx +181 -0
- package/src/client/skill-hub/components/SkillMetrics.tsx +124 -0
- package/src/client/skill-hub/components/SkillTestPanel.tsx +144 -0
- package/src/client/skill-hub/index.tsx +75 -0
- package/src/client/skill-hub/locale.ts +16 -0
- package/src/client/skill-hub/tools/InteractionSchemasProvider.tsx +59 -0
- package/src/client/skill-hub/tools/SkillHubCard.tsx +78 -0
- package/src/client/skill-hub/utils/jsonFields.ts +37 -0
- package/src/server/collections/agent-execution-spans.ts +129 -0
- package/src/server/collections/orchestrator-config.ts +17 -0
- package/src/server/collections/orchestrator-logs.ts +19 -2
- package/src/server/collections/skill-definitions.ts +128 -0
- package/src/server/collections/skill-executions.ts +94 -0
- package/src/server/collections/skill-worker-configs.ts +86 -0
- package/src/server/migrations/20260423000000-add-progress-fields.ts +50 -0
- package/src/server/migrations/20260425000000-add-interaction-schema.ts +35 -0
- package/src/server/migrations/20260427000000-add-tracing-detail-fields.ts +41 -0
- package/src/server/migrations/20260427000000-change-packages-to-text.ts +47 -0
- package/src/server/migrations/20260427000001-change-other-json-to-text.ts +57 -0
- package/src/server/migrations/20260429000000-add-llm-fields.ts +46 -0
- package/src/server/migrations/20260429000000-fix-inputargs-json-to-text.ts +38 -0
- package/src/server/migrations/20260503000000-add-orchestrator-trace-fields.ts +32 -0
- package/src/server/plugin.ts +51 -3
- package/src/server/resources/tracing.ts +187 -16
- package/src/server/services/CodeValidator.ts +159 -0
- package/src/server/services/ExecutionSpanService.ts +106 -0
- package/src/server/services/FileManager.ts +144 -0
- package/src/server/services/SandboxRunner.ts +205 -0
- package/src/server/services/SkillManager.ts +623 -0
- package/src/server/services/SkillRepositoryService.ts +142 -0
- package/src/server/services/WorkerEnvManager.ts +113 -0
- package/src/server/skill-hub/actions/git-import.ts +486 -0
- package/src/server/skill-hub/mcp/McpController.ts +86 -0
- package/src/server/skill-hub/plugin.ts +771 -0
- package/src/server/skill-hub/sandbox-config.json +6 -0
- package/src/server/skill-hub/tasks/SkillExecutionTask.ts +297 -0
- package/src/server/skill-hub/utils/json-fields.ts +57 -0
- package/src/server/tools/delegate-task.ts +1085 -147
- package/src/server/tools/skill-execute.ts +157 -0
|
@@ -0,0 +1,640 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
var __defProp = Object.defineProperty;
|
|
11
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
12
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
13
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
14
|
+
var __export = (target, all) => {
|
|
15
|
+
for (var name in all)
|
|
16
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
17
|
+
};
|
|
18
|
+
var __copyProps = (to, from, except, desc) => {
|
|
19
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
20
|
+
for (let key of __getOwnPropNames(from))
|
|
21
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
22
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
23
|
+
}
|
|
24
|
+
return to;
|
|
25
|
+
};
|
|
26
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
27
|
+
var SkillManager_exports = {};
|
|
28
|
+
__export(SkillManager_exports, {
|
|
29
|
+
SkillManager: () => SkillManager
|
|
30
|
+
});
|
|
31
|
+
module.exports = __toCommonJS(SkillManager_exports);
|
|
32
|
+
var import_json_fields = require("../skill-hub/utils/json-fields");
|
|
33
|
+
class SkillManager {
|
|
34
|
+
constructor(db) {
|
|
35
|
+
this.db = db;
|
|
36
|
+
}
|
|
37
|
+
async seedDefaults() {
|
|
38
|
+
const repo = this.db.getRepository("skillDefinitions");
|
|
39
|
+
const seeds = [
|
|
40
|
+
{
|
|
41
|
+
name: "generate-word-report",
|
|
42
|
+
title: "Generate Word Report",
|
|
43
|
+
description: "Generate a Word document (.docx) with title, content, and optional table data.",
|
|
44
|
+
language: "python",
|
|
45
|
+
codeTemplate: SEED_WORD_REPORT,
|
|
46
|
+
inputSchema: {
|
|
47
|
+
type: "object",
|
|
48
|
+
properties: {
|
|
49
|
+
title: { type: "string", description: "Report title" },
|
|
50
|
+
content: { type: "string", description: "Report body text" },
|
|
51
|
+
tableData: {
|
|
52
|
+
type: "array",
|
|
53
|
+
items: { type: "object" },
|
|
54
|
+
description: "Optional array of objects for table rows"
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
required: ["title", "content"]
|
|
58
|
+
},
|
|
59
|
+
packages: ["python-docx"],
|
|
60
|
+
timeoutSeconds: 30,
|
|
61
|
+
enabled: true,
|
|
62
|
+
toolScope: "CUSTOM"
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
name: "generate-excel",
|
|
66
|
+
title: "Generate Excel Spreadsheet",
|
|
67
|
+
description: "Generate an Excel file (.xlsx) with headers and row data.",
|
|
68
|
+
language: "python",
|
|
69
|
+
codeTemplate: SEED_EXCEL,
|
|
70
|
+
inputSchema: {
|
|
71
|
+
type: "object",
|
|
72
|
+
properties: {
|
|
73
|
+
sheetName: { type: "string", description: "Sheet name", default: "Sheet1" },
|
|
74
|
+
headers: { type: "array", items: { type: "string" }, description: "Column headers" },
|
|
75
|
+
rows: { type: "array", items: { type: "array" }, description: "Row data (array of arrays)" }
|
|
76
|
+
},
|
|
77
|
+
required: ["headers", "rows"]
|
|
78
|
+
},
|
|
79
|
+
packages: ["openpyxl"],
|
|
80
|
+
timeoutSeconds: 30,
|
|
81
|
+
enabled: true,
|
|
82
|
+
toolScope: "CUSTOM"
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
name: "generate-pdf-report",
|
|
86
|
+
title: "Generate PDF Report",
|
|
87
|
+
description: "Generate a professional PDF report with title, sections, and optional table. Suitable for CRM reports, customer summaries, and sales reports.",
|
|
88
|
+
language: "python",
|
|
89
|
+
codeTemplate: SEED_PDF_REPORT,
|
|
90
|
+
inputSchema: {
|
|
91
|
+
type: "object",
|
|
92
|
+
properties: {
|
|
93
|
+
title: { type: "string", description: "Report title" },
|
|
94
|
+
sections: {
|
|
95
|
+
type: "array",
|
|
96
|
+
items: {
|
|
97
|
+
type: "object",
|
|
98
|
+
properties: {
|
|
99
|
+
heading: { type: "string" },
|
|
100
|
+
body: { type: "string" }
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
description: "Array of {heading, body} sections"
|
|
104
|
+
},
|
|
105
|
+
tableData: {
|
|
106
|
+
type: "array",
|
|
107
|
+
items: { type: "object" },
|
|
108
|
+
description: "Optional array of objects for a summary table"
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
required: ["title", "sections"]
|
|
112
|
+
},
|
|
113
|
+
packages: ["reportlab"],
|
|
114
|
+
timeoutSeconds: 30,
|
|
115
|
+
enabled: true,
|
|
116
|
+
toolScope: "CUSTOM"
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
name: "generate-chart-image",
|
|
120
|
+
title: "Generate Chart Image",
|
|
121
|
+
description: "Generate a chart image (PNG) from data. Supports bar, line, pie charts. Useful for visualizing CRM metrics like sales, leads, revenue.",
|
|
122
|
+
language: "python",
|
|
123
|
+
codeTemplate: SEED_CHART,
|
|
124
|
+
inputSchema: {
|
|
125
|
+
type: "object",
|
|
126
|
+
properties: {
|
|
127
|
+
chartType: {
|
|
128
|
+
type: "string",
|
|
129
|
+
enum: ["bar", "line", "pie"],
|
|
130
|
+
description: "Chart type"
|
|
131
|
+
},
|
|
132
|
+
title: { type: "string", description: "Chart title" },
|
|
133
|
+
labels: { type: "array", items: { type: "string" }, description: "X-axis labels or pie labels" },
|
|
134
|
+
values: { type: "array", items: { type: "number" }, description: "Data values" },
|
|
135
|
+
xlabel: { type: "string", description: "X-axis label (bar/line only)" },
|
|
136
|
+
ylabel: { type: "string", description: "Y-axis label (bar/line only)" }
|
|
137
|
+
},
|
|
138
|
+
required: ["chartType", "title", "labels", "values"]
|
|
139
|
+
},
|
|
140
|
+
packages: ["matplotlib"],
|
|
141
|
+
timeoutSeconds: 30,
|
|
142
|
+
enabled: true,
|
|
143
|
+
toolScope: "CUSTOM"
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
name: "generate-invoice-pdf",
|
|
147
|
+
title: "Generate Invoice PDF",
|
|
148
|
+
description: "Generate a professional invoice PDF with company info, line items, and totals. For CRM billing and quotation workflows.",
|
|
149
|
+
language: "python",
|
|
150
|
+
codeTemplate: SEED_INVOICE,
|
|
151
|
+
inputSchema: {
|
|
152
|
+
type: "object",
|
|
153
|
+
properties: {
|
|
154
|
+
invoiceNumber: { type: "string", description: "Invoice number" },
|
|
155
|
+
date: { type: "string", description: "Invoice date (YYYY-MM-DD)" },
|
|
156
|
+
companyName: { type: "string", description: "Your company name" },
|
|
157
|
+
customerName: { type: "string", description: "Customer name" },
|
|
158
|
+
customerAddress: { type: "string", description: "Customer address" },
|
|
159
|
+
items: {
|
|
160
|
+
type: "array",
|
|
161
|
+
items: {
|
|
162
|
+
type: "object",
|
|
163
|
+
properties: {
|
|
164
|
+
description: { type: "string" },
|
|
165
|
+
quantity: { type: "number" },
|
|
166
|
+
unitPrice: { type: "number" }
|
|
167
|
+
}
|
|
168
|
+
},
|
|
169
|
+
description: "Line items with description, quantity, unitPrice"
|
|
170
|
+
},
|
|
171
|
+
currency: { type: "string", description: "Currency symbol", default: "$" },
|
|
172
|
+
notes: { type: "string", description: "Optional notes or payment terms" }
|
|
173
|
+
},
|
|
174
|
+
required: ["invoiceNumber", "date", "companyName", "customerName", "items"]
|
|
175
|
+
},
|
|
176
|
+
packages: ["reportlab"],
|
|
177
|
+
timeoutSeconds: 30,
|
|
178
|
+
enabled: true,
|
|
179
|
+
toolScope: "CUSTOM"
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
name: "data-summary-report",
|
|
183
|
+
title: "Data Summary & Analysis Report",
|
|
184
|
+
description: "Analyze tabular data and generate a Word report with summary statistics, top records, and insights. Ideal for CRM data analysis \u2014 leads, deals, customers.",
|
|
185
|
+
language: "python",
|
|
186
|
+
codeTemplate: SEED_DATA_SUMMARY,
|
|
187
|
+
inputSchema: {
|
|
188
|
+
type: "object",
|
|
189
|
+
properties: {
|
|
190
|
+
title: { type: "string", description: "Report title" },
|
|
191
|
+
data: {
|
|
192
|
+
type: "array",
|
|
193
|
+
items: { type: "object" },
|
|
194
|
+
description: "Array of data objects (e.g. deals, leads, customers)"
|
|
195
|
+
},
|
|
196
|
+
groupByField: { type: "string", description: "Optional field to group and summarize by" },
|
|
197
|
+
sortByField: { type: "string", description: "Optional field to sort by (descending)" },
|
|
198
|
+
topN: { type: "number", description: "Number of top records to include", default: 10 }
|
|
199
|
+
},
|
|
200
|
+
required: ["title", "data"]
|
|
201
|
+
},
|
|
202
|
+
packages: ["pandas", "python-docx"],
|
|
203
|
+
timeoutSeconds: 60,
|
|
204
|
+
enabled: true,
|
|
205
|
+
toolScope: "CUSTOM"
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
name: "data-transform",
|
|
209
|
+
title: "Data Transform (CSV/JSON)",
|
|
210
|
+
description: "Transform data array to CSV or JSON file for download.",
|
|
211
|
+
language: "node",
|
|
212
|
+
codeTemplate: SEED_DATA_TRANSFORM,
|
|
213
|
+
inputSchema: {
|
|
214
|
+
type: "object",
|
|
215
|
+
properties: {
|
|
216
|
+
data: { type: "array", items: { type: "object" }, description: "Array of data objects" },
|
|
217
|
+
format: { type: "string", enum: ["csv", "json"], description: "Output format" },
|
|
218
|
+
filename: { type: "string", description: "Output filename (without extension)" }
|
|
219
|
+
},
|
|
220
|
+
required: ["data", "format"]
|
|
221
|
+
},
|
|
222
|
+
packages: [],
|
|
223
|
+
timeoutSeconds: 30,
|
|
224
|
+
enabled: true,
|
|
225
|
+
toolScope: "CUSTOM"
|
|
226
|
+
}
|
|
227
|
+
];
|
|
228
|
+
for (const seed of seeds) {
|
|
229
|
+
try {
|
|
230
|
+
const count = await repo.count({ filter: { name: seed.name } });
|
|
231
|
+
if (count === 0) {
|
|
232
|
+
await repo.create({
|
|
233
|
+
values: {
|
|
234
|
+
...seed,
|
|
235
|
+
inputSchema: (0, import_json_fields.stringifyJsonText)(seed.inputSchema),
|
|
236
|
+
packages: (0, import_json_fields.stringifyJsonText)(seed.packages, [])
|
|
237
|
+
}
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
} catch (err) {
|
|
241
|
+
console.error(`[import-skill] Failed to insert ${seed.name}:`, err);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
const SEED_WORD_REPORT = `import os, json
|
|
247
|
+
from docx import Document
|
|
248
|
+
|
|
249
|
+
title = json.loads('''{{title}}''') if '{{title}}'.startswith('"') else '{{title}}'
|
|
250
|
+
content = json.loads('''{{content}}''') if '{{content}}'.startswith('"') else '{{content}}'
|
|
251
|
+
|
|
252
|
+
doc = Document()
|
|
253
|
+
doc.add_heading(title, 0)
|
|
254
|
+
doc.add_paragraph(content)
|
|
255
|
+
|
|
256
|
+
table_data_raw = '''{{tableData}}'''
|
|
257
|
+
if table_data_raw and table_data_raw != '{{' + 'tableData}}':
|
|
258
|
+
table_data = json.loads(table_data_raw)
|
|
259
|
+
if table_data and len(table_data) > 0:
|
|
260
|
+
headers = list(table_data[0].keys())
|
|
261
|
+
table = doc.add_table(rows=1, cols=len(headers))
|
|
262
|
+
table.style = 'Light Grid Accent 1'
|
|
263
|
+
for i, header in enumerate(headers):
|
|
264
|
+
table.rows[0].cells[i].text = str(header)
|
|
265
|
+
for row_data in table_data:
|
|
266
|
+
row = table.add_row()
|
|
267
|
+
for i, header in enumerate(headers):
|
|
268
|
+
row.cells[i].text = str(row_data.get(header, ''))
|
|
269
|
+
|
|
270
|
+
output_dir = os.environ.get('OUTPUT_DIR', '/output')
|
|
271
|
+
filepath = os.path.join(output_dir, 'report.docx')
|
|
272
|
+
doc.save(filepath)
|
|
273
|
+
print(f'Generated: report.docx')
|
|
274
|
+
`;
|
|
275
|
+
const SEED_EXCEL = `import os, json
|
|
276
|
+
import openpyxl
|
|
277
|
+
|
|
278
|
+
sheet_name_raw = '{{sheetName}}'
|
|
279
|
+
sheet_name = sheet_name_raw if sheet_name_raw != '{{' + 'sheetName}}' else 'Sheet1'
|
|
280
|
+
headers = json.loads('''{{headers}}''')
|
|
281
|
+
rows = json.loads('''{{rows}}''')
|
|
282
|
+
|
|
283
|
+
wb = openpyxl.Workbook()
|
|
284
|
+
ws = wb.active
|
|
285
|
+
ws.title = sheet_name
|
|
286
|
+
|
|
287
|
+
for col, header in enumerate(headers, 1):
|
|
288
|
+
ws.cell(row=1, column=col, value=header)
|
|
289
|
+
|
|
290
|
+
for row_idx, row_data in enumerate(rows, 2):
|
|
291
|
+
for col_idx, value in enumerate(row_data, 1):
|
|
292
|
+
ws.cell(row=row_idx, column=col_idx, value=value)
|
|
293
|
+
|
|
294
|
+
output_dir = os.environ.get('OUTPUT_DIR', '/output')
|
|
295
|
+
filepath = os.path.join(output_dir, 'data.xlsx')
|
|
296
|
+
wb.save(filepath)
|
|
297
|
+
print(f'Generated: data.xlsx')
|
|
298
|
+
`;
|
|
299
|
+
const SEED_PDF_REPORT = `import os, json
|
|
300
|
+
from reportlab.lib.pagesizes import A4
|
|
301
|
+
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
|
|
302
|
+
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle
|
|
303
|
+
from reportlab.lib import colors
|
|
304
|
+
from reportlab.lib.units import cm
|
|
305
|
+
|
|
306
|
+
title = json.loads('''{{title}}''') if '{{title}}'.startswith('"') else '{{title}}'
|
|
307
|
+
sections = json.loads('''{{sections}}''')
|
|
308
|
+
|
|
309
|
+
output_dir = os.environ.get('OUTPUT_DIR', '/output')
|
|
310
|
+
filepath = os.path.join(output_dir, 'report.pdf')
|
|
311
|
+
|
|
312
|
+
doc = SimpleDocTemplate(filepath, pagesize=A4,
|
|
313
|
+
topMargin=2*cm, bottomMargin=2*cm, leftMargin=2*cm, rightMargin=2*cm)
|
|
314
|
+
styles = getSampleStyleSheet()
|
|
315
|
+
title_style = ParagraphStyle('CustomTitle', parent=styles['Title'], fontSize=22, spaceAfter=20)
|
|
316
|
+
heading_style = ParagraphStyle('CustomHeading', parent=styles['Heading2'], fontSize=14, spaceBefore=16, spaceAfter=8)
|
|
317
|
+
body_style = styles['BodyText']
|
|
318
|
+
|
|
319
|
+
story = [Paragraph(title, title_style), Spacer(1, 12)]
|
|
320
|
+
|
|
321
|
+
for section in sections:
|
|
322
|
+
if section.get('heading'):
|
|
323
|
+
story.append(Paragraph(section['heading'], heading_style))
|
|
324
|
+
if section.get('body'):
|
|
325
|
+
for line in section['body'].split('\\n'):
|
|
326
|
+
story.append(Paragraph(line, body_style))
|
|
327
|
+
story.append(Spacer(1, 8))
|
|
328
|
+
|
|
329
|
+
table_data_raw = '''{{tableData}}'''
|
|
330
|
+
if table_data_raw and table_data_raw != '{{' + 'tableData}}':
|
|
331
|
+
td = json.loads(table_data_raw)
|
|
332
|
+
if td and len(td) > 0:
|
|
333
|
+
headers = list(td[0].keys())
|
|
334
|
+
data = [headers] + [[str(r.get(h, '')) for h in headers] for r in td]
|
|
335
|
+
t = Table(data, repeatRows=1)
|
|
336
|
+
t.setStyle(TableStyle([
|
|
337
|
+
('BACKGROUND', (0, 0), (-1, 0), colors.HexColor('#4472C4')),
|
|
338
|
+
('TEXTCOLOR', (0, 0), (-1, 0), colors.white),
|
|
339
|
+
('FONTSIZE', (0, 0), (-1, 0), 10),
|
|
340
|
+
('FONTSIZE', (0, 1), (-1, -1), 9),
|
|
341
|
+
('GRID', (0, 0), (-1, -1), 0.5, colors.grey),
|
|
342
|
+
('ROWBACKGROUNDS', (0, 1), (-1, -1), [colors.white, colors.HexColor('#D9E2F3')]),
|
|
343
|
+
]))
|
|
344
|
+
story.append(Spacer(1, 12))
|
|
345
|
+
story.append(t)
|
|
346
|
+
|
|
347
|
+
doc.build(story)
|
|
348
|
+
print('Generated: report.pdf')
|
|
349
|
+
`;
|
|
350
|
+
const SEED_PPTX = `import os, json
|
|
351
|
+
from pptx import Presentation
|
|
352
|
+
from pptx.util import Inches, Pt
|
|
353
|
+
from pptx.enum.text import PP_ALIGN
|
|
354
|
+
|
|
355
|
+
title = json.loads('''{{title}}''') if '{{title}}'.startswith('"') else '{{title}}'
|
|
356
|
+
subtitle_raw = '''{{subtitle}}'''
|
|
357
|
+
subtitle = json.loads(subtitle_raw) if subtitle_raw.startswith('"') else subtitle_raw if subtitle_raw != '{{' + 'subtitle}}' else ''
|
|
358
|
+
slides_data = json.loads('''{{slides}}''')
|
|
359
|
+
|
|
360
|
+
prs = Presentation()
|
|
361
|
+
prs.slide_width = Inches(13.333)
|
|
362
|
+
prs.slide_height = Inches(7.5)
|
|
363
|
+
|
|
364
|
+
# Title slide
|
|
365
|
+
slide = prs.slides.add_slide(prs.slide_layouts[0])
|
|
366
|
+
slide.shapes.title.text = title
|
|
367
|
+
if subtitle and slide.placeholders[1]:
|
|
368
|
+
slide.placeholders[1].text = subtitle
|
|
369
|
+
|
|
370
|
+
# Content slides
|
|
371
|
+
for s in slides_data:
|
|
372
|
+
slide = prs.slides.add_slide(prs.slide_layouts[1])
|
|
373
|
+
slide.shapes.title.text = s.get('title', '')
|
|
374
|
+
body = slide.placeholders[1].text_frame
|
|
375
|
+
body.clear()
|
|
376
|
+
for i, bullet in enumerate(s.get('bullets', [])):
|
|
377
|
+
if i == 0:
|
|
378
|
+
body.paragraphs[0].text = bullet
|
|
379
|
+
else:
|
|
380
|
+
p = body.add_paragraph()
|
|
381
|
+
p.text = bullet
|
|
382
|
+
body.paragraphs[-1].font.size = Pt(18)
|
|
383
|
+
|
|
384
|
+
output_dir = os.environ.get('OUTPUT_DIR', '/output')
|
|
385
|
+
filepath = os.path.join(output_dir, 'presentation.pptx')
|
|
386
|
+
prs.save(filepath)
|
|
387
|
+
print('Generated: presentation.pptx')
|
|
388
|
+
`;
|
|
389
|
+
const SEED_CHART = `import os, json
|
|
390
|
+
import matplotlib
|
|
391
|
+
matplotlib.use('Agg')
|
|
392
|
+
import matplotlib.pyplot as plt
|
|
393
|
+
|
|
394
|
+
chart_type = '{{chartType}}'
|
|
395
|
+
title = json.loads('''{{title}}''') if '{{title}}'.startswith('"') else '{{title}}'
|
|
396
|
+
labels = json.loads('''{{labels}}''')
|
|
397
|
+
values = json.loads('''{{values}}''')
|
|
398
|
+
xlabel_raw = '''{{xlabel}}'''
|
|
399
|
+
ylabel_raw = '''{{ylabel}}'''
|
|
400
|
+
xlabel = xlabel_raw if xlabel_raw != '{{' + 'xlabel}}' else ''
|
|
401
|
+
ylabel = ylabel_raw if ylabel_raw != '{{' + 'ylabel}}' else ''
|
|
402
|
+
|
|
403
|
+
fig, ax = plt.subplots(figsize=(10, 6))
|
|
404
|
+
colors = ['#4472C4', '#ED7D31', '#A5A5A5', '#FFC000', '#5B9BD5', '#70AD47', '#264478', '#9B59B6']
|
|
405
|
+
|
|
406
|
+
if chart_type == 'bar':
|
|
407
|
+
bars = ax.bar(labels, values, color=colors[:len(labels)])
|
|
408
|
+
for bar, val in zip(bars, values):
|
|
409
|
+
ax.text(bar.get_x() + bar.get_width()/2, bar.get_height() + max(values)*0.01,
|
|
410
|
+
f'{val:,.0f}' if isinstance(val, (int, float)) else str(val),
|
|
411
|
+
ha='center', va='bottom', fontsize=9)
|
|
412
|
+
if xlabel: ax.set_xlabel(xlabel)
|
|
413
|
+
if ylabel: ax.set_ylabel(ylabel)
|
|
414
|
+
elif chart_type == 'line':
|
|
415
|
+
ax.plot(labels, values, marker='o', linewidth=2, color='#4472C4', markersize=6)
|
|
416
|
+
for i, val in enumerate(values):
|
|
417
|
+
ax.annotate(f'{val:,.0f}', (labels[i], val), textcoords="offset points",
|
|
418
|
+
xytext=(0, 10), ha='center', fontsize=9)
|
|
419
|
+
if xlabel: ax.set_xlabel(xlabel)
|
|
420
|
+
if ylabel: ax.set_ylabel(ylabel)
|
|
421
|
+
elif chart_type == 'pie':
|
|
422
|
+
ax.pie(values, labels=labels, colors=colors[:len(labels)], autopct='%1.1f%%', startangle=90)
|
|
423
|
+
|
|
424
|
+
ax.set_title(title, fontsize=14, fontweight='bold', pad=15)
|
|
425
|
+
plt.tight_layout()
|
|
426
|
+
|
|
427
|
+
output_dir = os.environ.get('OUTPUT_DIR', '/output')
|
|
428
|
+
filepath = os.path.join(output_dir, 'chart.png')
|
|
429
|
+
fig.savefig(filepath, dpi=150, bbox_inches='tight')
|
|
430
|
+
plt.close()
|
|
431
|
+
print('Generated: chart.png')
|
|
432
|
+
`;
|
|
433
|
+
const SEED_INVOICE = `import os, json
|
|
434
|
+
from reportlab.lib.pagesizes import A4
|
|
435
|
+
from reportlab.pdfgen import canvas
|
|
436
|
+
from reportlab.lib.units import cm, mm
|
|
437
|
+
from reportlab.lib import colors
|
|
438
|
+
|
|
439
|
+
inv_number = json.loads('''{{invoiceNumber}}''') if '{{invoiceNumber}}'.startswith('"') else '{{invoiceNumber}}'
|
|
440
|
+
date = json.loads('''{{date}}''') if '{{date}}'.startswith('"') else '{{date}}'
|
|
441
|
+
company = json.loads('''{{companyName}}''') if '{{companyName}}'.startswith('"') else '{{companyName}}'
|
|
442
|
+
customer = json.loads('''{{customerName}}''') if '{{customerName}}'.startswith('"') else '{{customerName}}'
|
|
443
|
+
address_raw = '''{{customerAddress}}'''
|
|
444
|
+
address = json.loads(address_raw) if address_raw.startswith('"') else address_raw if address_raw != '{{' + 'customerAddress}}' else ''
|
|
445
|
+
items = json.loads('''{{items}}''')
|
|
446
|
+
currency_raw = '''{{currency}}'''
|
|
447
|
+
currency = currency_raw if currency_raw != '{{' + 'currency}}' else '$'
|
|
448
|
+
notes_raw = '''{{notes}}'''
|
|
449
|
+
notes = json.loads(notes_raw) if notes_raw.startswith('"') else notes_raw if notes_raw != '{{' + 'notes}}' else ''
|
|
450
|
+
|
|
451
|
+
output_dir = os.environ.get('OUTPUT_DIR', '/output')
|
|
452
|
+
filepath = os.path.join(output_dir, f'invoice_{inv_number}.pdf')
|
|
453
|
+
w, h = A4
|
|
454
|
+
c = canvas.Canvas(filepath, pagesize=A4)
|
|
455
|
+
|
|
456
|
+
# Header
|
|
457
|
+
c.setFont('Helvetica-Bold', 24)
|
|
458
|
+
c.setFillColor(colors.HexColor('#2C3E50'))
|
|
459
|
+
c.drawString(2*cm, h - 2.5*cm, 'INVOICE')
|
|
460
|
+
c.setFont('Helvetica', 10)
|
|
461
|
+
c.setFillColor(colors.HexColor('#7F8C8D'))
|
|
462
|
+
c.drawRightString(w - 2*cm, h - 2.5*cm, f'#{inv_number}')
|
|
463
|
+
c.drawRightString(w - 2*cm, h - 3*cm, f'Date: {date}')
|
|
464
|
+
|
|
465
|
+
# Company & Customer
|
|
466
|
+
y = h - 4.5*cm
|
|
467
|
+
c.setFillColor(colors.HexColor('#2C3E50'))
|
|
468
|
+
c.setFont('Helvetica-Bold', 11)
|
|
469
|
+
c.drawString(2*cm, y, 'From:')
|
|
470
|
+
c.drawString(10*cm, y, 'To:')
|
|
471
|
+
c.setFont('Helvetica', 10)
|
|
472
|
+
c.setFillColor(colors.black)
|
|
473
|
+
c.drawString(2*cm, y - 0.5*cm, company)
|
|
474
|
+
c.drawString(10*cm, y - 0.5*cm, customer)
|
|
475
|
+
if address:
|
|
476
|
+
for i, line in enumerate(address.split('\\n')):
|
|
477
|
+
c.drawString(10*cm, y - (1 + i*0.5)*cm, line)
|
|
478
|
+
|
|
479
|
+
# Table header
|
|
480
|
+
y = h - 8*cm
|
|
481
|
+
c.setFillColor(colors.HexColor('#4472C4'))
|
|
482
|
+
c.rect(2*cm, y - 0.1*cm, w - 4*cm, 0.7*cm, fill=1, stroke=0)
|
|
483
|
+
c.setFillColor(colors.white)
|
|
484
|
+
c.setFont('Helvetica-Bold', 9)
|
|
485
|
+
c.drawString(2.2*cm, y + 0.1*cm, 'Description')
|
|
486
|
+
c.drawRightString(12*cm, y + 0.1*cm, 'Qty')
|
|
487
|
+
c.drawRightString(15*cm, y + 0.1*cm, 'Unit Price')
|
|
488
|
+
c.drawRightString(w - 2.2*cm, y + 0.1*cm, 'Amount')
|
|
489
|
+
|
|
490
|
+
# Items
|
|
491
|
+
c.setFillColor(colors.black)
|
|
492
|
+
c.setFont('Helvetica', 9)
|
|
493
|
+
total = 0
|
|
494
|
+
for i, item in enumerate(items):
|
|
495
|
+
row_y = y - (i + 1) * 0.6*cm
|
|
496
|
+
qty = item.get('quantity', 0)
|
|
497
|
+
price = item.get('unitPrice', 0)
|
|
498
|
+
amount = qty * price
|
|
499
|
+
total += amount
|
|
500
|
+
if i % 2 == 1:
|
|
501
|
+
c.setFillColor(colors.HexColor('#F0F4F8'))
|
|
502
|
+
c.rect(2*cm, row_y - 0.1*cm, w - 4*cm, 0.6*cm, fill=1, stroke=0)
|
|
503
|
+
c.setFillColor(colors.black)
|
|
504
|
+
c.drawString(2.2*cm, row_y + 0.1*cm, str(item.get('description', '')))
|
|
505
|
+
c.drawRightString(12*cm, row_y + 0.1*cm, str(qty))
|
|
506
|
+
c.drawRightString(15*cm, row_y + 0.1*cm, f'{currency}{price:,.2f}')
|
|
507
|
+
c.drawRightString(w - 2.2*cm, row_y + 0.1*cm, f'{currency}{amount:,.2f}')
|
|
508
|
+
|
|
509
|
+
# Total
|
|
510
|
+
total_y = y - (len(items) + 1.5) * 0.6*cm
|
|
511
|
+
c.setStrokeColor(colors.HexColor('#4472C4'))
|
|
512
|
+
c.line(12*cm, total_y + 0.4*cm, w - 2*cm, total_y + 0.4*cm)
|
|
513
|
+
c.setFont('Helvetica-Bold', 11)
|
|
514
|
+
c.drawRightString(15*cm, total_y, 'Total:')
|
|
515
|
+
c.setFillColor(colors.HexColor('#2C3E50'))
|
|
516
|
+
c.drawRightString(w - 2.2*cm, total_y, f'{currency}{total:,.2f}')
|
|
517
|
+
|
|
518
|
+
# Notes
|
|
519
|
+
if notes:
|
|
520
|
+
notes_y = total_y - 2*cm
|
|
521
|
+
c.setFillColor(colors.HexColor('#7F8C8D'))
|
|
522
|
+
c.setFont('Helvetica-Bold', 9)
|
|
523
|
+
c.drawString(2*cm, notes_y, 'Notes:')
|
|
524
|
+
c.setFont('Helvetica', 9)
|
|
525
|
+
c.setFillColor(colors.black)
|
|
526
|
+
for i, line in enumerate(notes.split('\\n')):
|
|
527
|
+
c.drawString(2*cm, notes_y - (i + 1) * 0.4*cm, line)
|
|
528
|
+
|
|
529
|
+
c.save()
|
|
530
|
+
print(f'Generated: invoice_{inv_number}.pdf')
|
|
531
|
+
`;
|
|
532
|
+
const SEED_DATA_SUMMARY = `import os, json
|
|
533
|
+
import pandas as pd
|
|
534
|
+
from docx import Document
|
|
535
|
+
from docx.shared import Inches, Pt
|
|
536
|
+
from docx.enum.table import WD_TABLE_ALIGNMENT
|
|
537
|
+
|
|
538
|
+
title = json.loads('''{{title}}''') if '{{title}}'.startswith('"') else '{{title}}'
|
|
539
|
+
raw_data = json.loads('''{{data}}''')
|
|
540
|
+
group_by_raw = '''{{groupByField}}'''
|
|
541
|
+
group_by = group_by_raw if group_by_raw != '{{' + 'groupByField}}' else None
|
|
542
|
+
sort_by_raw = '''{{sortByField}}'''
|
|
543
|
+
sort_by = sort_by_raw if sort_by_raw != '{{' + 'sortByField}}' else None
|
|
544
|
+
top_n_raw = '''{{topN}}'''
|
|
545
|
+
top_n = int(top_n_raw) if top_n_raw != '{{' + 'topN}}' else 10
|
|
546
|
+
|
|
547
|
+
df = pd.DataFrame(raw_data)
|
|
548
|
+
doc = Document()
|
|
549
|
+
doc.add_heading(title, 0)
|
|
550
|
+
|
|
551
|
+
# Overview
|
|
552
|
+
doc.add_heading('Overview', level=1)
|
|
553
|
+
doc.add_paragraph(f'Total records: {len(df)}')
|
|
554
|
+
doc.add_paragraph(f'Fields: {", ".join(df.columns.tolist())}')
|
|
555
|
+
|
|
556
|
+
# Numeric summary
|
|
557
|
+
num_cols = df.select_dtypes(include='number').columns.tolist()
|
|
558
|
+
if num_cols:
|
|
559
|
+
doc.add_heading('Numeric Summary', level=1)
|
|
560
|
+
stats = df[num_cols].describe().round(2)
|
|
561
|
+
table = doc.add_table(rows=len(stats) + 1, cols=len(num_cols) + 1)
|
|
562
|
+
table.style = 'Light Grid Accent 1'
|
|
563
|
+
table.alignment = WD_TABLE_ALIGNMENT.CENTER
|
|
564
|
+
table.rows[0].cells[0].text = 'Metric'
|
|
565
|
+
for j, col in enumerate(num_cols):
|
|
566
|
+
table.rows[0].cells[j + 1].text = col
|
|
567
|
+
for i, (idx, row) in enumerate(stats.iterrows()):
|
|
568
|
+
table.rows[i + 1].cells[0].text = str(idx)
|
|
569
|
+
for j, col in enumerate(num_cols):
|
|
570
|
+
table.rows[i + 1].cells[j + 1].text = str(row[col])
|
|
571
|
+
|
|
572
|
+
# Group-by analysis
|
|
573
|
+
if group_by and group_by in df.columns:
|
|
574
|
+
doc.add_heading(f'Grouped by: {group_by}', level=1)
|
|
575
|
+
grouped = df.groupby(group_by)
|
|
576
|
+
summary_rows = []
|
|
577
|
+
for name, group in grouped:
|
|
578
|
+
row_info = {'Group': str(name), 'Count': len(group)}
|
|
579
|
+
for nc in num_cols:
|
|
580
|
+
row_info[f'{nc} (sum)'] = round(group[nc].sum(), 2)
|
|
581
|
+
row_info[f'{nc} (avg)'] = round(group[nc].mean(), 2)
|
|
582
|
+
summary_rows.append(row_info)
|
|
583
|
+
if summary_rows:
|
|
584
|
+
headers = list(summary_rows[0].keys())
|
|
585
|
+
table = doc.add_table(rows=len(summary_rows) + 1, cols=len(headers))
|
|
586
|
+
table.style = 'Light Grid Accent 1'
|
|
587
|
+
for j, h in enumerate(headers):
|
|
588
|
+
table.rows[0].cells[j].text = h
|
|
589
|
+
for i, sr in enumerate(summary_rows):
|
|
590
|
+
for j, h in enumerate(headers):
|
|
591
|
+
table.rows[i + 1].cells[j].text = str(sr[h])
|
|
592
|
+
|
|
593
|
+
# Top records
|
|
594
|
+
if sort_by and sort_by in df.columns:
|
|
595
|
+
df_sorted = df.sort_values(sort_by, ascending=False)
|
|
596
|
+
else:
|
|
597
|
+
df_sorted = df
|
|
598
|
+
top = df_sorted.head(top_n)
|
|
599
|
+
doc.add_heading(f'Top {top_n} Records', level=1)
|
|
600
|
+
cols = top.columns.tolist()
|
|
601
|
+
table = doc.add_table(rows=len(top) + 1, cols=len(cols))
|
|
602
|
+
table.style = 'Light Grid Accent 1'
|
|
603
|
+
for j, col in enumerate(cols):
|
|
604
|
+
table.rows[0].cells[j].text = str(col)
|
|
605
|
+
for i, (_, row) in enumerate(top.iterrows()):
|
|
606
|
+
for j, col in enumerate(cols):
|
|
607
|
+
table.rows[i + 1].cells[j].text = str(row[col])
|
|
608
|
+
|
|
609
|
+
output_dir = os.environ.get('OUTPUT_DIR', '/output')
|
|
610
|
+
filepath = os.path.join(output_dir, 'summary_report.docx')
|
|
611
|
+
doc.save(filepath)
|
|
612
|
+
print('Generated: summary_report.docx')
|
|
613
|
+
`;
|
|
614
|
+
const SEED_DATA_TRANSFORM = `const fs = require('fs');
|
|
615
|
+
const path = require('path');
|
|
616
|
+
|
|
617
|
+
const data = {{data}};
|
|
618
|
+
const format = '{{format}}';
|
|
619
|
+
const filename = '{{filename}}' !== '{{' + 'filename}}' ? '{{filename}}' : 'result';
|
|
620
|
+
const outputDir = process.env.OUTPUT_DIR || '/output';
|
|
621
|
+
|
|
622
|
+
if (format === 'csv') {
|
|
623
|
+
const headers = Object.keys(data[0] || {});
|
|
624
|
+
const csv = [
|
|
625
|
+
headers.join(','),
|
|
626
|
+
...data.map(row => headers.map(h => JSON.stringify(row[h] ?? '')).join(','))
|
|
627
|
+
].join('\\n');
|
|
628
|
+
const outPath = path.join(outputDir, filename + '.csv');
|
|
629
|
+
fs.writeFileSync(outPath, csv, 'utf-8');
|
|
630
|
+
console.log('Generated: ' + filename + '.csv');
|
|
631
|
+
} else {
|
|
632
|
+
const outPath = path.join(outputDir, filename + '.json');
|
|
633
|
+
fs.writeFileSync(outPath, JSON.stringify(data, null, 2), 'utf-8');
|
|
634
|
+
console.log('Generated: ' + filename + '.json');
|
|
635
|
+
}
|
|
636
|
+
`;
|
|
637
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
638
|
+
0 && (module.exports = {
|
|
639
|
+
SkillManager
|
|
640
|
+
});
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export interface SkillPackageMetadata {
|
|
2
|
+
path: string;
|
|
3
|
+
metadata: Record<string, any>;
|
|
4
|
+
instructions: string;
|
|
5
|
+
code: string | null;
|
|
6
|
+
}
|
|
7
|
+
export declare class SkillRepositoryService {
|
|
8
|
+
private baseDir;
|
|
9
|
+
constructor(storagePath: string);
|
|
10
|
+
/**
|
|
11
|
+
* Extract a zip file to the repository.
|
|
12
|
+
* Returns parsed metadata from SKILL.md / skill.yaml
|
|
13
|
+
*/
|
|
14
|
+
extractSkillPackage(skillName: string, zipFilePath: string): Promise<SkillPackageMetadata>;
|
|
15
|
+
getSkillPath(skillName: string): string;
|
|
16
|
+
getSkillCode(skillName: string): string | null;
|
|
17
|
+
copySkillPackageTo(skillName: string, destDir: string): void;
|
|
18
|
+
readSkillPackage(packageDir: string): SkillPackageMetadata;
|
|
19
|
+
copyDirectoryTo(srcDir: string, destDir: string): void;
|
|
20
|
+
private getSkillCodeFromDir;
|
|
21
|
+
private aggregateOtherMarkdownFiles;
|
|
22
|
+
}
|