pilotswarm-sdk 0.1.3
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/dist/agent-loader.d.ts +61 -0
- package/dist/agent-loader.d.ts.map +1 -0
- package/dist/agent-loader.js +212 -0
- package/dist/agent-loader.js.map +1 -0
- package/dist/artifact-tools.d.ts +31 -0
- package/dist/artifact-tools.d.ts.map +1 -0
- package/dist/artifact-tools.js +190 -0
- package/dist/artifact-tools.js.map +1 -0
- package/dist/blob-store.d.ts +73 -0
- package/dist/blob-store.d.ts.map +1 -0
- package/dist/blob-store.js +220 -0
- package/dist/blob-store.js.map +1 -0
- package/dist/client.d.ts +159 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +676 -0
- package/dist/client.js.map +1 -0
- package/dist/cms.d.ts +129 -0
- package/dist/cms.d.ts.map +1 -0
- package/dist/cms.js +313 -0
- package/dist/cms.js.map +1 -0
- package/dist/index.d.ts +44 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +42 -0
- package/dist/index.js.map +1 -0
- package/dist/managed-session.d.ts +70 -0
- package/dist/managed-session.d.ts.map +1 -0
- package/dist/managed-session.js +717 -0
- package/dist/managed-session.js.map +1 -0
- package/dist/management-client.d.ts +171 -0
- package/dist/management-client.d.ts.map +1 -0
- package/dist/management-client.js +401 -0
- package/dist/management-client.js.map +1 -0
- package/dist/mcp-loader.d.ts +50 -0
- package/dist/mcp-loader.d.ts.map +1 -0
- package/dist/mcp-loader.js +83 -0
- package/dist/mcp-loader.js.map +1 -0
- package/dist/model-providers.d.ts +143 -0
- package/dist/model-providers.d.ts.map +1 -0
- package/dist/model-providers.js +228 -0
- package/dist/model-providers.js.map +1 -0
- package/dist/orchestration-registry.d.ts +7 -0
- package/dist/orchestration-registry.d.ts.map +1 -0
- package/dist/orchestration-registry.js +49 -0
- package/dist/orchestration-registry.js.map +1 -0
- package/dist/orchestration.d.ts +36 -0
- package/dist/orchestration.d.ts.map +1 -0
- package/dist/orchestration.js +1357 -0
- package/dist/orchestration.js.map +1 -0
- package/dist/orchestration_1_0_0.d.ts +20 -0
- package/dist/orchestration_1_0_0.d.ts.map +1 -0
- package/dist/orchestration_1_0_0.js +497 -0
- package/dist/orchestration_1_0_0.js.map +1 -0
- package/dist/orchestration_1_0_1.d.ts +19 -0
- package/dist/orchestration_1_0_1.d.ts.map +1 -0
- package/dist/orchestration_1_0_1.js +546 -0
- package/dist/orchestration_1_0_1.js.map +1 -0
- package/dist/orchestration_1_0_10.d.ts +36 -0
- package/dist/orchestration_1_0_10.d.ts.map +1 -0
- package/dist/orchestration_1_0_10.js +1253 -0
- package/dist/orchestration_1_0_10.js.map +1 -0
- package/dist/orchestration_1_0_11.d.ts +36 -0
- package/dist/orchestration_1_0_11.d.ts.map +1 -0
- package/dist/orchestration_1_0_11.js +1255 -0
- package/dist/orchestration_1_0_11.js.map +1 -0
- package/dist/orchestration_1_0_12.d.ts +36 -0
- package/dist/orchestration_1_0_12.d.ts.map +1 -0
- package/dist/orchestration_1_0_12.js +1250 -0
- package/dist/orchestration_1_0_12.js.map +1 -0
- package/dist/orchestration_1_0_13.d.ts +36 -0
- package/dist/orchestration_1_0_13.d.ts.map +1 -0
- package/dist/orchestration_1_0_13.js +1260 -0
- package/dist/orchestration_1_0_13.js.map +1 -0
- package/dist/orchestration_1_0_14.d.ts +36 -0
- package/dist/orchestration_1_0_14.d.ts.map +1 -0
- package/dist/orchestration_1_0_14.js +1258 -0
- package/dist/orchestration_1_0_14.js.map +1 -0
- package/dist/orchestration_1_0_15.d.ts +36 -0
- package/dist/orchestration_1_0_15.d.ts.map +1 -0
- package/dist/orchestration_1_0_15.js +1266 -0
- package/dist/orchestration_1_0_15.js.map +1 -0
- package/dist/orchestration_1_0_16.d.ts +36 -0
- package/dist/orchestration_1_0_16.d.ts.map +1 -0
- package/dist/orchestration_1_0_16.js +1275 -0
- package/dist/orchestration_1_0_16.js.map +1 -0
- package/dist/orchestration_1_0_17.d.ts +36 -0
- package/dist/orchestration_1_0_17.d.ts.map +1 -0
- package/dist/orchestration_1_0_17.js +1314 -0
- package/dist/orchestration_1_0_17.js.map +1 -0
- package/dist/orchestration_1_0_18.d.ts +36 -0
- package/dist/orchestration_1_0_18.d.ts.map +1 -0
- package/dist/orchestration_1_0_18.js +1328 -0
- package/dist/orchestration_1_0_18.js.map +1 -0
- package/dist/orchestration_1_0_19.d.ts +36 -0
- package/dist/orchestration_1_0_19.d.ts.map +1 -0
- package/dist/orchestration_1_0_19.js +1324 -0
- package/dist/orchestration_1_0_19.js.map +1 -0
- package/dist/orchestration_1_0_2.d.ts +19 -0
- package/dist/orchestration_1_0_2.d.ts.map +1 -0
- package/dist/orchestration_1_0_2.js +749 -0
- package/dist/orchestration_1_0_2.js.map +1 -0
- package/dist/orchestration_1_0_20.d.ts +36 -0
- package/dist/orchestration_1_0_20.d.ts.map +1 -0
- package/dist/orchestration_1_0_20.js +1347 -0
- package/dist/orchestration_1_0_20.js.map +1 -0
- package/dist/orchestration_1_0_3.d.ts +19 -0
- package/dist/orchestration_1_0_3.d.ts.map +1 -0
- package/dist/orchestration_1_0_3.js +826 -0
- package/dist/orchestration_1_0_3.js.map +1 -0
- package/dist/orchestration_1_0_4.d.ts +19 -0
- package/dist/orchestration_1_0_4.d.ts.map +1 -0
- package/dist/orchestration_1_0_4.js +1020 -0
- package/dist/orchestration_1_0_4.js.map +1 -0
- package/dist/orchestration_1_0_5.d.ts +19 -0
- package/dist/orchestration_1_0_5.d.ts.map +1 -0
- package/dist/orchestration_1_0_5.js +1027 -0
- package/dist/orchestration_1_0_5.js.map +1 -0
- package/dist/orchestration_1_0_6.d.ts +19 -0
- package/dist/orchestration_1_0_6.d.ts.map +1 -0
- package/dist/orchestration_1_0_6.js +1034 -0
- package/dist/orchestration_1_0_6.js.map +1 -0
- package/dist/orchestration_1_0_7.d.ts +19 -0
- package/dist/orchestration_1_0_7.d.ts.map +1 -0
- package/dist/orchestration_1_0_7.js +1085 -0
- package/dist/orchestration_1_0_7.js.map +1 -0
- package/dist/orchestration_1_0_8.d.ts +36 -0
- package/dist/orchestration_1_0_8.d.ts.map +1 -0
- package/dist/orchestration_1_0_8.js +1106 -0
- package/dist/orchestration_1_0_8.js.map +1 -0
- package/dist/orchestration_1_0_9.d.ts +36 -0
- package/dist/orchestration_1_0_9.d.ts.map +1 -0
- package/dist/orchestration_1_0_9.js +1207 -0
- package/dist/orchestration_1_0_9.js.map +1 -0
- package/dist/prompt-layering.d.ts +16 -0
- package/dist/prompt-layering.d.ts.map +1 -0
- package/dist/prompt-layering.js +60 -0
- package/dist/prompt-layering.js.map +1 -0
- package/dist/resourcemgr-tools.d.ts +27 -0
- package/dist/resourcemgr-tools.d.ts.map +1 -0
- package/dist/resourcemgr-tools.js +638 -0
- package/dist/resourcemgr-tools.js.map +1 -0
- package/dist/session-dumper.d.ts +26 -0
- package/dist/session-dumper.d.ts.map +1 -0
- package/dist/session-dumper.js +272 -0
- package/dist/session-dumper.js.map +1 -0
- package/dist/session-manager.d.ts +152 -0
- package/dist/session-manager.d.ts.map +1 -0
- package/dist/session-manager.js +493 -0
- package/dist/session-manager.js.map +1 -0
- package/dist/session-proxy.d.ts +68 -0
- package/dist/session-proxy.d.ts.map +1 -0
- package/dist/session-proxy.js +665 -0
- package/dist/session-proxy.js.map +1 -0
- package/dist/session-store.d.ts +35 -0
- package/dist/session-store.d.ts.map +1 -0
- package/dist/session-store.js +88 -0
- package/dist/session-store.js.map +1 -0
- package/dist/skills.d.ts +31 -0
- package/dist/skills.d.ts.map +1 -0
- package/dist/skills.js +93 -0
- package/dist/skills.js.map +1 -0
- package/dist/sweeper-tools.d.ts +28 -0
- package/dist/sweeper-tools.d.ts.map +1 -0
- package/dist/sweeper-tools.js +332 -0
- package/dist/sweeper-tools.js.map +1 -0
- package/dist/types.d.ts +498 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +9 -0
- package/dist/types.js.map +1 -0
- package/dist/worker.d.ts +128 -0
- package/dist/worker.d.ts.map +1 -0
- package/dist/worker.js +562 -0
- package/dist/worker.js.map +1 -0
- package/package.json +74 -0
- package/plugins/mgmt/agents/pilotswarm.agent.md +59 -0
- package/plugins/mgmt/agents/resourcemgr.agent.md +111 -0
- package/plugins/mgmt/agents/sweeper.agent.md +67 -0
- package/plugins/mgmt/skills/resourcemgr/SKILL.md +41 -0
- package/plugins/mgmt/skills/resourcemgr/tools.json +1 -0
- package/plugins/mgmt/skills/sweeper/SKILL.md +44 -0
- package/plugins/mgmt/skills/sweeper/tools.json +1 -0
- package/plugins/system/agents/default.agent.md +58 -0
- package/plugins/system/skills/durable-timers/SKILL.md +39 -0
- package/plugins/system/skills/sub-agents/SKILL.md +75 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent loader — reads .agent.md files with YAML frontmatter from disk.
|
|
3
|
+
*
|
|
4
|
+
* Agent file format (standard Copilot .agent.md):
|
|
5
|
+
* ---
|
|
6
|
+
* name: planner
|
|
7
|
+
* description: Creates structured plans for complex tasks.
|
|
8
|
+
* tools:
|
|
9
|
+
* - view
|
|
10
|
+
* - grep
|
|
11
|
+
* ---
|
|
12
|
+
*
|
|
13
|
+
* # Planner Agent
|
|
14
|
+
* You are a planning agent...
|
|
15
|
+
*
|
|
16
|
+
* The YAML frontmatter becomes CustomAgentConfig fields (name, description, tools).
|
|
17
|
+
* The markdown body becomes the agent's `prompt`.
|
|
18
|
+
*
|
|
19
|
+
* @module
|
|
20
|
+
*/
|
|
21
|
+
/**
|
|
22
|
+
* Derive a deterministic UUID from a system agent ID slug.
|
|
23
|
+
* All workers and clients produce the same UUID for the same slug.
|
|
24
|
+
*/
|
|
25
|
+
export declare function systemAgentUUID(slug: string): string;
|
|
26
|
+
/**
|
|
27
|
+
* Derive a deterministic UUID for a system child agent from its parent session
|
|
28
|
+
* and child slug. This keeps system children like sweeper/resource manager
|
|
29
|
+
* stable across restarts while avoiding collisions between different parents.
|
|
30
|
+
*/
|
|
31
|
+
export declare function systemChildAgentUUID(parentSessionId: string, slug: string): string;
|
|
32
|
+
export interface AgentConfig {
|
|
33
|
+
name: string;
|
|
34
|
+
description?: string;
|
|
35
|
+
prompt: string;
|
|
36
|
+
tools?: string[] | null;
|
|
37
|
+
/** If true, this is a system agent started automatically by workers. */
|
|
38
|
+
system?: boolean;
|
|
39
|
+
/** Deterministic ID slug for system agents (e.g. "sweeper"). Used to derive a fixed session UUID. */
|
|
40
|
+
id?: string;
|
|
41
|
+
/** Display title for the session list (e.g. "Resource Manager Agent"). Falls back to capitalized name + " Agent". */
|
|
42
|
+
title?: string;
|
|
43
|
+
/** Parent system agent ID slug (e.g. "pilotswarm"). Makes this a sub-agent of the parent. */
|
|
44
|
+
parent?: string;
|
|
45
|
+
/** Splash banner (blessed markup) shown in the TUI when the session is selected. */
|
|
46
|
+
splash?: string;
|
|
47
|
+
/** Initial prompt to send when the system agent is first created. */
|
|
48
|
+
initialPrompt?: string;
|
|
49
|
+
/** Source plugin namespace (e.g. "pilotswarm", "smelter"). Set by the worker during plugin loading. */
|
|
50
|
+
namespace?: string;
|
|
51
|
+
/** Internal: identifies which prompt layering path this agent should use. */
|
|
52
|
+
promptLayerKind?: "app-agent" | "app-system-agent" | "pilotswarm-system-agent";
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Load all .agent.md files from a directory and convert to CustomAgentConfig[].
|
|
56
|
+
*
|
|
57
|
+
* @param agentsDir - Path to the agents directory.
|
|
58
|
+
* @returns Array of agent configs. Files that fail to parse are skipped with a warning.
|
|
59
|
+
*/
|
|
60
|
+
export declare function loadAgentFiles(agentsDir: string): AgentConfig[];
|
|
61
|
+
//# sourceMappingURL=agent-loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-loader.d.ts","sourceRoot":"","sources":["../src/agent-loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAQH;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAYpD;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,eAAe,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAclF;AAID,MAAM,WAAW,WAAW;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACxB,wEAAwE;IACxE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,qGAAqG;IACrG,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,qHAAqH;IACrH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6FAA6F;IAC7F,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oFAAoF;IACpF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qEAAqE;IACrE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,uGAAuG;IACvG,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6EAA6E;IAC7E,eAAe,CAAC,EAAE,WAAW,GAAG,kBAAkB,GAAG,yBAAyB,CAAC;CAClF;AA+GD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,WAAW,EAAE,CA+C/D"}
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent loader — reads .agent.md files with YAML frontmatter from disk.
|
|
3
|
+
*
|
|
4
|
+
* Agent file format (standard Copilot .agent.md):
|
|
5
|
+
* ---
|
|
6
|
+
* name: planner
|
|
7
|
+
* description: Creates structured plans for complex tasks.
|
|
8
|
+
* tools:
|
|
9
|
+
* - view
|
|
10
|
+
* - grep
|
|
11
|
+
* ---
|
|
12
|
+
*
|
|
13
|
+
* # Planner Agent
|
|
14
|
+
* You are a planning agent...
|
|
15
|
+
*
|
|
16
|
+
* The YAML frontmatter becomes CustomAgentConfig fields (name, description, tools).
|
|
17
|
+
* The markdown body becomes the agent's `prompt`.
|
|
18
|
+
*
|
|
19
|
+
* @module
|
|
20
|
+
*/
|
|
21
|
+
import fs from "node:fs";
|
|
22
|
+
import path from "node:path";
|
|
23
|
+
import crypto from "node:crypto";
|
|
24
|
+
// ─── System Agent UUID ──────────────────────────────────────────
|
|
25
|
+
/**
|
|
26
|
+
* Derive a deterministic UUID from a system agent ID slug.
|
|
27
|
+
* All workers and clients produce the same UUID for the same slug.
|
|
28
|
+
*/
|
|
29
|
+
export function systemAgentUUID(slug) {
|
|
30
|
+
const hash = crypto.createHash("sha256")
|
|
31
|
+
.update("pilotswarm-system-agent:")
|
|
32
|
+
.update(slug)
|
|
33
|
+
.digest("hex");
|
|
34
|
+
return [
|
|
35
|
+
hash.slice(0, 8),
|
|
36
|
+
hash.slice(8, 12),
|
|
37
|
+
hash.slice(12, 16),
|
|
38
|
+
hash.slice(16, 20),
|
|
39
|
+
hash.slice(20, 32),
|
|
40
|
+
].join("-");
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Derive a deterministic UUID for a system child agent from its parent session
|
|
44
|
+
* and child slug. This keeps system children like sweeper/resource manager
|
|
45
|
+
* stable across restarts while avoiding collisions between different parents.
|
|
46
|
+
*/
|
|
47
|
+
export function systemChildAgentUUID(parentSessionId, slug) {
|
|
48
|
+
const hash = crypto.createHash("sha256")
|
|
49
|
+
.update("pilotswarm-system-child-agent:")
|
|
50
|
+
.update(parentSessionId)
|
|
51
|
+
.update(":")
|
|
52
|
+
.update(slug)
|
|
53
|
+
.digest("hex");
|
|
54
|
+
return [
|
|
55
|
+
hash.slice(0, 8),
|
|
56
|
+
hash.slice(8, 12),
|
|
57
|
+
hash.slice(12, 16),
|
|
58
|
+
hash.slice(16, 20),
|
|
59
|
+
hash.slice(20, 32),
|
|
60
|
+
].join("-");
|
|
61
|
+
}
|
|
62
|
+
// ─── Frontmatter Parser ─────────────────────────────────────────
|
|
63
|
+
/**
|
|
64
|
+
* Parse YAML frontmatter from an .agent.md file.
|
|
65
|
+
* Handles simple `key: value` pairs and YAML list syntax for `tools`.
|
|
66
|
+
*/
|
|
67
|
+
function parseAgentFrontmatter(content) {
|
|
68
|
+
const meta = {};
|
|
69
|
+
if (!content.startsWith("---")) {
|
|
70
|
+
return { meta, body: content };
|
|
71
|
+
}
|
|
72
|
+
const endIdx = content.indexOf("\n---", 3);
|
|
73
|
+
if (endIdx === -1) {
|
|
74
|
+
return { meta, body: content };
|
|
75
|
+
}
|
|
76
|
+
const yamlBlock = content.slice(4, endIdx); // skip opening "---\n"
|
|
77
|
+
const lines = yamlBlock.split("\n");
|
|
78
|
+
let currentKey = null;
|
|
79
|
+
let multilineValue = null;
|
|
80
|
+
let currentBlockStyle = null;
|
|
81
|
+
const flushMultiline = () => {
|
|
82
|
+
if (multilineValue !== null && currentKey) {
|
|
83
|
+
const val = multilineValue.join("\n").trimEnd();
|
|
84
|
+
if (currentKey === "splash")
|
|
85
|
+
meta.splash = val;
|
|
86
|
+
else if (currentKey === "initialPrompt") {
|
|
87
|
+
// For > (folded) scalars, collapse newlines to spaces
|
|
88
|
+
meta.initialPrompt = currentBlockStyle === ">" ? val.replace(/\n/g, " ").trim() : val;
|
|
89
|
+
}
|
|
90
|
+
multilineValue = null;
|
|
91
|
+
currentBlockStyle = null;
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
for (const line of lines) {
|
|
95
|
+
const trimmed = line.trim();
|
|
96
|
+
// Collecting multiline block scalar value (YAML | syntax)
|
|
97
|
+
if (multilineValue !== null) {
|
|
98
|
+
// A new top-level key ends the block
|
|
99
|
+
if (/^[a-zA-Z]/.test(line) && line.includes(":")) {
|
|
100
|
+
flushMultiline();
|
|
101
|
+
// fall through to key-value parsing below
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
// Strip 2-space indent if present, preserve content
|
|
105
|
+
multilineValue.push(line.startsWith(" ") ? line.slice(2) : line);
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
// YAML list item (e.g. " - view")
|
|
110
|
+
if (trimmed.startsWith("- ") && currentKey === "tools") {
|
|
111
|
+
if (!meta.tools)
|
|
112
|
+
meta.tools = [];
|
|
113
|
+
meta.tools.push(trimmed.slice(2).trim());
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
// Key-value pair
|
|
117
|
+
const colonIdx = line.indexOf(":");
|
|
118
|
+
if (colonIdx === -1)
|
|
119
|
+
continue;
|
|
120
|
+
const key = line.slice(0, colonIdx).trim();
|
|
121
|
+
let value = line.slice(colonIdx + 1).trim();
|
|
122
|
+
// Strip surrounding quotes
|
|
123
|
+
if ((value.startsWith('"') && value.endsWith('"')) ||
|
|
124
|
+
(value.startsWith("'") && value.endsWith("'"))) {
|
|
125
|
+
value = value.slice(1, -1);
|
|
126
|
+
}
|
|
127
|
+
currentKey = key;
|
|
128
|
+
if (key === "name")
|
|
129
|
+
meta.name = value;
|
|
130
|
+
else if (key === "description")
|
|
131
|
+
meta.description = value;
|
|
132
|
+
else if (key === "system")
|
|
133
|
+
meta.system = value === "true";
|
|
134
|
+
else if (key === "id")
|
|
135
|
+
meta.id = value;
|
|
136
|
+
else if (key === "title")
|
|
137
|
+
meta.title = value;
|
|
138
|
+
else if (key === "parent")
|
|
139
|
+
meta.parent = value;
|
|
140
|
+
else if (key === "tools" && value) {
|
|
141
|
+
// Inline array: tools: [view, grep]
|
|
142
|
+
meta.tools = value.replace(/[\[\]]/g, "").split(",").map(s => s.trim()).filter(Boolean);
|
|
143
|
+
}
|
|
144
|
+
else if (key === "tools" && !value) {
|
|
145
|
+
// Will be followed by list items
|
|
146
|
+
meta.tools = [];
|
|
147
|
+
}
|
|
148
|
+
else if ((key === "splash" || key === "initialPrompt") && (value === "|" || value === ">")) {
|
|
149
|
+
// YAML block scalar (| literal, > folded)
|
|
150
|
+
currentBlockStyle = value;
|
|
151
|
+
multilineValue = [];
|
|
152
|
+
}
|
|
153
|
+
else if (key === "splash") {
|
|
154
|
+
meta.splash = value;
|
|
155
|
+
}
|
|
156
|
+
else if (key === "initialPrompt") {
|
|
157
|
+
meta.initialPrompt = value;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
flushMultiline();
|
|
161
|
+
const body = content.slice(endIdx + 4).trimStart(); // skip closing "---\n"
|
|
162
|
+
return { meta, body };
|
|
163
|
+
}
|
|
164
|
+
// ─── Loader ─────────────────────────────────────────────────────
|
|
165
|
+
/**
|
|
166
|
+
* Load all .agent.md files from a directory and convert to CustomAgentConfig[].
|
|
167
|
+
*
|
|
168
|
+
* @param agentsDir - Path to the agents directory.
|
|
169
|
+
* @returns Array of agent configs. Files that fail to parse are skipped with a warning.
|
|
170
|
+
*/
|
|
171
|
+
export function loadAgentFiles(agentsDir) {
|
|
172
|
+
const absDir = path.resolve(agentsDir);
|
|
173
|
+
if (!fs.existsSync(absDir)) {
|
|
174
|
+
return [];
|
|
175
|
+
}
|
|
176
|
+
const entries = fs.readdirSync(absDir, { withFileTypes: true });
|
|
177
|
+
const agents = [];
|
|
178
|
+
for (const entry of entries) {
|
|
179
|
+
if (!entry.isFile() || !entry.name.endsWith(".agent.md"))
|
|
180
|
+
continue;
|
|
181
|
+
const filePath = path.join(absDir, entry.name);
|
|
182
|
+
try {
|
|
183
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
184
|
+
const { meta, body } = parseAgentFrontmatter(content);
|
|
185
|
+
if (!meta.name) {
|
|
186
|
+
// Derive name from filename: planner.agent.md → planner
|
|
187
|
+
meta.name = entry.name.replace(/\.agent\.md$/, "");
|
|
188
|
+
}
|
|
189
|
+
if (!body.trim()) {
|
|
190
|
+
console.warn(`[agent-loader] Skipping ${entry.name}: empty prompt body`);
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
193
|
+
agents.push({
|
|
194
|
+
name: meta.name,
|
|
195
|
+
description: meta.description,
|
|
196
|
+
prompt: body,
|
|
197
|
+
tools: meta.tools && meta.tools.length > 0 ? meta.tools : null,
|
|
198
|
+
system: meta.system,
|
|
199
|
+
id: meta.id,
|
|
200
|
+
title: meta.title,
|
|
201
|
+
parent: meta.parent,
|
|
202
|
+
splash: meta.splash,
|
|
203
|
+
initialPrompt: meta.initialPrompt,
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
catch (err) {
|
|
207
|
+
console.warn(`[agent-loader] Failed to parse ${entry.name}: ${err.message}`);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return agents;
|
|
211
|
+
}
|
|
212
|
+
//# sourceMappingURL=agent-loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-loader.js","sourceRoot":"","sources":["../src/agent-loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Artifact Tools — allow agents to read/write markdown files via Azure Blob Storage.
|
|
3
|
+
*
|
|
4
|
+
* Three tools:
|
|
5
|
+
* - `write_artifact` — upload a file to blob storage
|
|
6
|
+
* - `read_artifact` — read a file from another session's artifacts
|
|
7
|
+
* - `export_artifact` — return an artifact:// URI for TUI on-demand download
|
|
8
|
+
*
|
|
9
|
+
* Plus a discovery tool:
|
|
10
|
+
* - `list_artifacts` — list files in a session's artifact folder
|
|
11
|
+
*
|
|
12
|
+
* Agents communicate via artifacts: Agent A writes, Agent B reads.
|
|
13
|
+
* For TUI download, the agent calls `export_artifact` which returns an
|
|
14
|
+
* `artifact://sessionId/filename` URI. The TUI detects these URIs and
|
|
15
|
+
* lets the user download on demand from blob storage directly.
|
|
16
|
+
*
|
|
17
|
+
* @module
|
|
18
|
+
* @internal
|
|
19
|
+
*/
|
|
20
|
+
import type { Tool } from "@github/copilot-sdk";
|
|
21
|
+
import type { SessionBlobStore } from "./blob-store.js";
|
|
22
|
+
/**
|
|
23
|
+
* Create artifact tools bound to the given blob store.
|
|
24
|
+
*
|
|
25
|
+
* The `sessionId` for write/export operations is injected by the tool handler
|
|
26
|
+
* via the session context (the agent's own session ID).
|
|
27
|
+
*/
|
|
28
|
+
export declare function createArtifactTools(opts: {
|
|
29
|
+
blobStore: SessionBlobStore;
|
|
30
|
+
}): Tool<any>[];
|
|
31
|
+
//# sourceMappingURL=artifact-tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artifact-tools.d.ts","sourceRoot":"","sources":["../src/artifact-tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAExD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE;IACtC,SAAS,EAAE,gBAAgB,CAAC;CAC/B,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CA4Ld"}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Artifact Tools — allow agents to read/write markdown files via Azure Blob Storage.
|
|
3
|
+
*
|
|
4
|
+
* Three tools:
|
|
5
|
+
* - `write_artifact` — upload a file to blob storage
|
|
6
|
+
* - `read_artifact` — read a file from another session's artifacts
|
|
7
|
+
* - `export_artifact` — return an artifact:// URI for TUI on-demand download
|
|
8
|
+
*
|
|
9
|
+
* Plus a discovery tool:
|
|
10
|
+
* - `list_artifacts` — list files in a session's artifact folder
|
|
11
|
+
*
|
|
12
|
+
* Agents communicate via artifacts: Agent A writes, Agent B reads.
|
|
13
|
+
* For TUI download, the agent calls `export_artifact` which returns an
|
|
14
|
+
* `artifact://sessionId/filename` URI. The TUI detects these URIs and
|
|
15
|
+
* lets the user download on demand from blob storage directly.
|
|
16
|
+
*
|
|
17
|
+
* @module
|
|
18
|
+
* @internal
|
|
19
|
+
*/
|
|
20
|
+
import { defineTool } from "@github/copilot-sdk";
|
|
21
|
+
/**
|
|
22
|
+
* Create artifact tools bound to the given blob store.
|
|
23
|
+
*
|
|
24
|
+
* The `sessionId` for write/export operations is injected by the tool handler
|
|
25
|
+
* via the session context (the agent's own session ID).
|
|
26
|
+
*/
|
|
27
|
+
export function createArtifactTools(opts) {
|
|
28
|
+
const { blobStore } = opts;
|
|
29
|
+
// ── write_artifact ─────────────────────────────────────────
|
|
30
|
+
const writeTool = defineTool("write_artifact", {
|
|
31
|
+
description: "Write a file (typically markdown) to shared blob storage. " +
|
|
32
|
+
"Other agents can read it via `read_artifact`. " +
|
|
33
|
+
"To make it downloadable by the TUI user, call `export_artifact` afterwards.\n\n" +
|
|
34
|
+
"The file is stored under the current session's artifact folder. " +
|
|
35
|
+
"Maximum file size: 1MB.",
|
|
36
|
+
parameters: {
|
|
37
|
+
type: "object",
|
|
38
|
+
properties: {
|
|
39
|
+
filename: {
|
|
40
|
+
type: "string",
|
|
41
|
+
description: "Filename including extension, e.g. 'report.md' or 'analysis.json'. " +
|
|
42
|
+
"No path separators allowed.",
|
|
43
|
+
},
|
|
44
|
+
content: {
|
|
45
|
+
type: "string",
|
|
46
|
+
description: "The full file content to write.",
|
|
47
|
+
},
|
|
48
|
+
contentType: {
|
|
49
|
+
type: "string",
|
|
50
|
+
description: "MIME type. Default: 'text/markdown'. Use 'application/json' for JSON, etc.",
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
required: ["filename", "content"],
|
|
54
|
+
},
|
|
55
|
+
handler: async (params, context) => {
|
|
56
|
+
const sessionId = context?.durableSessionId;
|
|
57
|
+
if (!sessionId) {
|
|
58
|
+
return JSON.stringify({ error: "No session context — cannot determine artifact path." });
|
|
59
|
+
}
|
|
60
|
+
try {
|
|
61
|
+
const blobPath = await blobStore.uploadArtifact(sessionId, params.filename, params.content, params.contentType ?? "text/markdown");
|
|
62
|
+
return JSON.stringify({
|
|
63
|
+
success: true,
|
|
64
|
+
sessionId,
|
|
65
|
+
filename: params.filename,
|
|
66
|
+
blobPath,
|
|
67
|
+
sizeBytes: params.content.length,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
return JSON.stringify({ error: err.message });
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
// ── read_artifact ──────────────────────────────────────────
|
|
76
|
+
const readTool = defineTool("read_artifact", {
|
|
77
|
+
description: "Read a file from any session's artifact storage. " +
|
|
78
|
+
"Use this to read files written by other agents via `write_artifact`. " +
|
|
79
|
+
"You need the session ID and filename.",
|
|
80
|
+
parameters: {
|
|
81
|
+
type: "object",
|
|
82
|
+
properties: {
|
|
83
|
+
sessionId: {
|
|
84
|
+
type: "string",
|
|
85
|
+
description: "The session ID that owns the artifact. Use your own session ID for your own files, " +
|
|
86
|
+
"or another agent's session ID to read their files.",
|
|
87
|
+
},
|
|
88
|
+
filename: {
|
|
89
|
+
type: "string",
|
|
90
|
+
description: "The filename to read, e.g. 'report.md'.",
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
required: ["sessionId", "filename"],
|
|
94
|
+
},
|
|
95
|
+
handler: async (params) => {
|
|
96
|
+
try {
|
|
97
|
+
const content = await blobStore.downloadArtifact(params.sessionId, params.filename);
|
|
98
|
+
return JSON.stringify({
|
|
99
|
+
success: true,
|
|
100
|
+
sessionId: params.sessionId,
|
|
101
|
+
filename: params.filename,
|
|
102
|
+
content,
|
|
103
|
+
sizeBytes: content.length,
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
catch (err) {
|
|
107
|
+
return JSON.stringify({ error: err.message });
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
});
|
|
111
|
+
// ── list_artifacts ─────────────────────────────────────────
|
|
112
|
+
const listTool = defineTool("list_artifacts", {
|
|
113
|
+
description: "List all artifact files in a session's storage folder. " +
|
|
114
|
+
"Returns filenames that can be read with `read_artifact`.",
|
|
115
|
+
parameters: {
|
|
116
|
+
type: "object",
|
|
117
|
+
properties: {
|
|
118
|
+
sessionId: {
|
|
119
|
+
type: "string",
|
|
120
|
+
description: "The session ID to list artifacts for. " +
|
|
121
|
+
"Omit or leave empty to list your own session's artifacts.",
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
required: [],
|
|
125
|
+
},
|
|
126
|
+
handler: async (params, context) => {
|
|
127
|
+
const targetId = params.sessionId || context?.durableSessionId;
|
|
128
|
+
if (!targetId) {
|
|
129
|
+
return JSON.stringify({ error: "No session ID provided or available from context." });
|
|
130
|
+
}
|
|
131
|
+
try {
|
|
132
|
+
const files = await blobStore.listArtifacts(targetId);
|
|
133
|
+
return JSON.stringify({
|
|
134
|
+
success: true,
|
|
135
|
+
sessionId: targetId,
|
|
136
|
+
files,
|
|
137
|
+
count: files.length,
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
catch (err) {
|
|
141
|
+
return JSON.stringify({ error: err.message });
|
|
142
|
+
}
|
|
143
|
+
},
|
|
144
|
+
});
|
|
145
|
+
// ── export_artifact ────────────────────────────────────────
|
|
146
|
+
const exportTool = defineTool("export_artifact", {
|
|
147
|
+
description: "Make a file available for the TUI user to download. " +
|
|
148
|
+
"Returns an artifact:// link that the TUI renders as a clickable download. " +
|
|
149
|
+
"You MUST include the returned artifact:// link in your response text " +
|
|
150
|
+
"so the user can see and download it.\n\n" +
|
|
151
|
+
"You must have written the file with `write_artifact` first.",
|
|
152
|
+
parameters: {
|
|
153
|
+
type: "object",
|
|
154
|
+
properties: {
|
|
155
|
+
filename: {
|
|
156
|
+
type: "string",
|
|
157
|
+
description: "The filename to export, e.g. 'report.md'.",
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
required: ["filename"],
|
|
161
|
+
},
|
|
162
|
+
handler: async (params, context) => {
|
|
163
|
+
const sessionId = context?.durableSessionId;
|
|
164
|
+
if (!sessionId) {
|
|
165
|
+
return JSON.stringify({ error: "No session context — cannot determine artifact path." });
|
|
166
|
+
}
|
|
167
|
+
try {
|
|
168
|
+
// Verify the file exists
|
|
169
|
+
const exists = await blobStore.artifactExists(sessionId, params.filename);
|
|
170
|
+
if (!exists) {
|
|
171
|
+
return JSON.stringify({
|
|
172
|
+
error: `Artifact '${params.filename}' not found. Write it first with write_artifact.`,
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
const artifactUri = `artifact://${sessionId}/${params.filename}`;
|
|
176
|
+
return JSON.stringify({
|
|
177
|
+
success: true,
|
|
178
|
+
filename: params.filename,
|
|
179
|
+
artifactLink: artifactUri,
|
|
180
|
+
message: "Include the artifactLink in your response. The TUI will render it as a downloadable link.",
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
catch (err) {
|
|
184
|
+
return JSON.stringify({ error: err.message });
|
|
185
|
+
}
|
|
186
|
+
},
|
|
187
|
+
});
|
|
188
|
+
return [writeTool, readTool, listTool, exportTool];
|
|
189
|
+
}
|
|
190
|
+
//# sourceMappingURL=artifact-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artifact-tools.js","sourceRoot":"","sources":["../src/artifact-tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { type SessionStateStore } from "./session-store.js";
|
|
2
|
+
/**
|
|
3
|
+
* Manages session state in Azure Blob Storage.
|
|
4
|
+
*
|
|
5
|
+
* - `dehydrate()` — tar + upload session dir, remove local files
|
|
6
|
+
* - `hydrate()` — download + untar session dir
|
|
7
|
+
* - `checkpoint()` — tar + upload without removing local files
|
|
8
|
+
* - `exists()` / `delete()` — blob lifecycle
|
|
9
|
+
*
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
12
|
+
export declare class SessionBlobStore implements SessionStateStore {
|
|
13
|
+
private containerClient;
|
|
14
|
+
private connectionString;
|
|
15
|
+
private containerName;
|
|
16
|
+
private credential;
|
|
17
|
+
private sessionStateDir;
|
|
18
|
+
constructor(connectionString: string, containerName?: string, sessionStateDir?: string);
|
|
19
|
+
/**
|
|
20
|
+
* Dehydrate a session: tar, upload, remove local files.
|
|
21
|
+
* Frees the worker slot for another session.
|
|
22
|
+
*/
|
|
23
|
+
dehydrate(sessionId: string, meta?: Record<string, unknown>): Promise<void>;
|
|
24
|
+
/**
|
|
25
|
+
* Hydrate a session: download tar from blob, extract to local disk.
|
|
26
|
+
* No-op if local session files already exist.
|
|
27
|
+
*/
|
|
28
|
+
hydrate(sessionId: string): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Checkpoint: upload current session state to blob without removing local files.
|
|
31
|
+
* Used for crash resilience — the session stays warm in memory.
|
|
32
|
+
*/
|
|
33
|
+
checkpoint(sessionId: string): Promise<void>;
|
|
34
|
+
/** Check if a dehydrated session exists in blob storage. */
|
|
35
|
+
exists(sessionId: string): Promise<boolean>;
|
|
36
|
+
/** Delete a dehydrated session from blob storage. */
|
|
37
|
+
delete(sessionId: string): Promise<void>;
|
|
38
|
+
private artifactBlobPath;
|
|
39
|
+
/**
|
|
40
|
+
* Upload an artifact file (e.g. .md) to blob storage.
|
|
41
|
+
* Max 1MB content.
|
|
42
|
+
*/
|
|
43
|
+
uploadArtifact(sessionId: string, filename: string, content: string, contentType?: string): Promise<string>;
|
|
44
|
+
/**
|
|
45
|
+
* Download an artifact file from blob storage.
|
|
46
|
+
* Returns the file content as a string.
|
|
47
|
+
*/
|
|
48
|
+
downloadArtifact(sessionId: string, filename: string): Promise<string>;
|
|
49
|
+
/**
|
|
50
|
+
* List artifact files for a session.
|
|
51
|
+
* Returns filenames (not full blob paths).
|
|
52
|
+
*/
|
|
53
|
+
listArtifacts(sessionId: string): Promise<string[]>;
|
|
54
|
+
/**
|
|
55
|
+
* Check if an artifact exists.
|
|
56
|
+
*/
|
|
57
|
+
artifactExists(sessionId: string, filename: string): Promise<boolean>;
|
|
58
|
+
/**
|
|
59
|
+
* Generate a short-lived read-only SAS URL for an artifact.
|
|
60
|
+
* The TUI uses this to download files without needing blob credentials.
|
|
61
|
+
*
|
|
62
|
+
* @param sessionId Session that owns the artifact
|
|
63
|
+
* @param filename Artifact filename
|
|
64
|
+
* @param expiryMinutes How long the URL is valid (default: 1 minute)
|
|
65
|
+
* @returns Full SAS URL string
|
|
66
|
+
*/
|
|
67
|
+
generateArtifactSasUrl(sessionId: string, filename: string, expiryMinutes?: number): string;
|
|
68
|
+
/**
|
|
69
|
+
* Delete all artifacts for a session.
|
|
70
|
+
*/
|
|
71
|
+
deleteArtifacts(sessionId: string): Promise<number>;
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=blob-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blob-store.d.ts","sourceRoot":"","sources":["../src/blob-store.ts"],"names":[],"mappings":"AAUA,OAAO,EAGH,KAAK,iBAAiB,EAIzB,MAAM,oBAAoB,CAAC;AAE5B;;;;;;;;;GASG;AACH,qBAAa,gBAAiB,YAAW,iBAAiB;IACtD,OAAO,CAAC,eAAe,CAAC;IACxB,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,UAAU,CAA2C;IAC7D,OAAO,CAAC,eAAe,CAAS;gBAEpB,gBAAgB,EAAE,MAAM,EAAE,aAAa,SAAqB,EAAE,eAAe,CAAC,EAAE,MAAM;IAelG;;;OAGG;IACG,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IA0BjF;;;OAGG;IACG,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAmB/C;;;OAGG;IACG,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBlD,4DAA4D;IACtD,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKjD,qDAAqD;IAC/C,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAO9C,OAAO,CAAC,gBAAgB;IAMxB;;;OAGG;IACG,cAAc,CAChB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,WAAW,SAAkB,GAC9B,OAAO,CAAC,MAAM,CAAC;IAalB;;;OAGG;IACG,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAW5E;;;OAGG;IACG,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAUzD;;OAEG;IACG,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAK3E;;;;;;;;OAQG;IACH,sBAAsB,CAClB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,aAAa,SAAI,GAClB,MAAM;IAyBT;;OAEG;IACG,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAS5D"}
|