@memberjunction/ai-agents 5.43.0 → 5.44.0
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 +8 -0
- package/dist/DuplicateReasoningAgentProvider.d.ts +35 -0
- package/dist/DuplicateReasoningAgentProvider.d.ts.map +1 -0
- package/dist/DuplicateReasoningAgentProvider.js +95 -0
- package/dist/DuplicateReasoningAgentProvider.js.map +1 -0
- package/dist/MJAIAgentRequestEntityServer.d.ts +7 -0
- package/dist/MJAIAgentRequestEntityServer.d.ts.map +1 -1
- package/dist/MJAIAgentRequestEntityServer.js +28 -1
- package/dist/MJAIAgentRequestEntityServer.js.map +1 -1
- package/dist/SkillImportExportService.d.ts +63 -0
- package/dist/SkillImportExportService.d.ts.map +1 -0
- package/dist/SkillImportExportService.js +148 -0
- package/dist/SkillImportExportService.js.map +1 -0
- package/dist/SkillMarkdownConverter.d.ts +82 -0
- package/dist/SkillMarkdownConverter.d.ts.map +1 -0
- package/dist/SkillMarkdownConverter.js +145 -0
- package/dist/SkillMarkdownConverter.js.map +1 -0
- package/dist/agent-types/loop-agent-response-type.d.ts +17 -2
- package/dist/agent-types/loop-agent-response-type.d.ts.map +1 -1
- package/dist/agent-types/loop-agent-response-type.js.map +1 -1
- package/dist/agent-types/loop-agent-type.d.ts.map +1 -1
- package/dist/agent-types/loop-agent-type.js +33 -1
- package/dist/agent-types/loop-agent-type.js.map +1 -1
- package/dist/base-agent.d.ts +373 -12
- package/dist/base-agent.d.ts.map +1 -1
- package/dist/base-agent.js +1007 -78
- package/dist/base-agent.js.map +1 -1
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -1
- package/dist/memory-manager-agent.d.ts +39 -0
- package/dist/memory-manager-agent.d.ts.map +1 -1
- package/dist/memory-manager-agent.js +118 -5
- package/dist/memory-manager-agent.js.map +1 -1
- package/dist/operations/AISkillMarkdownOperations.d.ts +11 -0
- package/dist/operations/AISkillMarkdownOperations.d.ts.map +1 -0
- package/dist/operations/AISkillMarkdownOperations.js +57 -0
- package/dist/operations/AISkillMarkdownOperations.js.map +1 -0
- package/dist/prompt-component-resolver.d.ts +73 -0
- package/dist/prompt-component-resolver.d.ts.map +1 -0
- package/dist/prompt-component-resolver.js +166 -0
- package/dist/prompt-component-resolver.js.map +1 -0
- package/dist/realtime/agent-media-library.d.ts +65 -0
- package/dist/realtime/agent-media-library.d.ts.map +1 -0
- package/dist/realtime/agent-media-library.js +160 -0
- package/dist/realtime/agent-media-library.js.map +1 -0
- package/dist/realtime/client-context-channel-server.d.ts +59 -0
- package/dist/realtime/client-context-channel-server.d.ts.map +1 -0
- package/dist/realtime/client-context-channel-server.js +78 -0
- package/dist/realtime/client-context-channel-server.js.map +1 -0
- package/dist/realtime/media-channel-server.d.ts +73 -0
- package/dist/realtime/media-channel-server.d.ts.map +1 -0
- package/dist/realtime/media-channel-server.js +145 -0
- package/dist/realtime/media-channel-server.js.map +1 -0
- package/dist/realtime/realtime-channel-server-data-context.d.ts +42 -0
- package/dist/realtime/realtime-channel-server-data-context.d.ts.map +1 -0
- package/dist/realtime/realtime-channel-server-data-context.js +29 -0
- package/dist/realtime/realtime-channel-server-data-context.js.map +1 -0
- package/dist/realtime/realtime-channel-server-host.d.ts.map +1 -1
- package/dist/realtime/realtime-channel-server-host.js +8 -2
- package/dist/realtime/realtime-channel-server-host.js.map +1 -1
- package/dist/realtime/realtime-client-session-service.d.ts +85 -5
- package/dist/realtime/realtime-client-session-service.d.ts.map +1 -1
- package/dist/realtime/realtime-client-session-service.js +234 -25
- package/dist/realtime/realtime-client-session-service.js.map +1 -1
- package/dist/realtime/realtime-coagent-config.d.ts +82 -3
- package/dist/realtime/realtime-coagent-config.d.ts.map +1 -1
- package/dist/realtime/realtime-coagent-config.js +147 -6
- package/dist/realtime/realtime-coagent-config.js.map +1 -1
- package/dist/realtime/realtime-recording-capture.d.ts +125 -0
- package/dist/realtime/realtime-recording-capture.d.ts.map +1 -0
- package/dist/realtime/realtime-recording-capture.js +317 -0
- package/dist/realtime/realtime-recording-capture.js.map +1 -0
- package/dist/realtime/realtime-recording-store.d.ts +105 -0
- package/dist/realtime/realtime-recording-store.d.ts.map +1 -0
- package/dist/realtime/realtime-recording-store.js +216 -0
- package/dist/realtime/realtime-recording-store.js.map +1 -0
- package/dist/realtime/realtime-session-runner.d.ts +33 -2
- package/dist/realtime/realtime-session-runner.d.ts.map +1 -1
- package/dist/realtime/realtime-session-runner.js +45 -2
- package/dist/realtime/realtime-session-runner.js.map +1 -1
- package/dist/realtime/realtime-tool-broker.d.ts +41 -3
- package/dist/realtime/realtime-tool-broker.d.ts.map +1 -1
- package/dist/realtime/realtime-tool-broker.js +67 -3
- package/dist/realtime/realtime-tool-broker.js.map +1 -1
- package/package.json +18 -17
package/README.md
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
Complete framework for building and executing AI agents in MemberJunction. Provides the `BaseAgent` execution engine, pluggable agent type system (Loop and Flow agents), hierarchical sub-agent orchestration, action execution, memory management with notes and examples, payload management, conversation context with message lifecycle management, and reranker integration.
|
|
4
4
|
|
|
5
|
+
It also provides two capability layers any agent can opt into:
|
|
6
|
+
|
|
7
|
+
- **Skills** — reusable capability bundles (instructions + Actions + sub-agents) an agent activates mid-run via a progressive-disclosure catalog, gated per-agent (`AIAgent.AcceptsSkills`), shareable via Resource Permissions, and portable via **SKILL.md** import/export.
|
|
8
|
+
- **Plan Mode** — a per-request human-in-the-loop gate (`ExecuteAgentParams.planMode`) that makes an agent present a plan and get it approved before executing any Actions or Sub-Agents, built on the existing `MJ: AI Agent Requests` pause/resume flow.
|
|
9
|
+
|
|
10
|
+
**See the [Agent Skills & Plan Mode Guide](../../../guides/AGENT_SKILLS_AND_PLAN_MODE_GUIDE.md)** for the full architecture, the three-layer gate, the SKILL.md format, and the plan-approval flow.
|
|
11
|
+
|
|
5
12
|
## Architecture
|
|
6
13
|
|
|
7
14
|
```mermaid
|
|
@@ -190,6 +197,7 @@ Key pieces in this package:
|
|
|
190
197
|
- **`RealtimeClientSessionService`** (`src/realtime/realtime-client-session-service.ts`) — the server half of the **client-direct** topology (the shipped audio path: the browser opens its own provider socket with a server-minted ephemeral token, while the server keeps prompt/tool authority and executes every relayed tool call). `PrepareClientSession` resolves the Realtime model, assembles the companion system prompt + memory context (including a resumed session's prior-leg transcript when the caller threads one in), mints the `ClientRealtimeSessionConfig`, and creates the co-agent **observability run** (an `AIAgentRun` + linked `AIPromptRun` stamped with the co-agent's `AgentID`, plus a single `Prompt`-type `AIAgentRunStep` whose `TargetLogID` points at the prompt run — finalized with a `Success` stamp by `FinalizeCoAgentRun`). `ExecuteRelayedTool` runs relayed calls through the shared broker — registering each in a per-session **in-flight delegation registry** so `CancelInFlightDelegations(sessionId, callId?)` (the engine behind the `CancelRealtimeSessionTool` mutation) can abort them on explicit user cancel — including resuming a paused (`AwaitingFeedback`) interactive run and creating artifacts from delegated-run payloads.
|
|
191
198
|
- **`RealtimeChannelServerHost`** (`src/realtime/realtime-channel-server-host.ts`) — the **server half** of the interactive-channel plugin registry (`MJ: AI Agent Channels.ServerPluginClass`; base class `BaseRealtimeChannelServer` in `@memberjunction/ai`, mirroring the browser's `BaseRealtimeChannelClient`). A `BaseSingleton` host that resolves the ACTIVE registry rows at session mint into one fresh plugin instance per session (unregistered keys skip with a log, never fatal) and routes the durable lifecycle into them: session started (`SessionManager.CreateSession`), channel-state saves pre-persistence (a plugin may validate/normalize the persisted state of record — it can transform a save, never lose or block one), and session close from every provenance (explicit / janitor / shutdown / error), with a brief post-close linger so the client's final state flush still routes through the plugin before disposal. Every hook is failure-isolated — a throwing plugin can never break a live call.
|
|
192
199
|
- **`WhiteboardChannelServer`** (`src/realtime/whiteboard-channel-server.ts`, key `'WhiteboardChannelServer'`) — the reference server channel plugin: guards the Whiteboard's persisted state of record by validating each landed save parses as a JSON object (flagging corrupt payloads at save time instead of at the next resume) and canonicalizing valid payloads to compact JSON. `LoadWhiteboardChannelServer()` is invoked from MJServer's `agentSessions` module.
|
|
200
|
+
- **`MediaChannelServer`** (`src/realtime/media-channel-server.ts`, key `'MediaChannelServer'`) — the server channel plugin for the **Media** surface. Like the Whiteboard it canonicalizes the channel's persisted media state, and additionally resolves the agent's **media kit** at session start: it implements `IRealtimeChannelServerDataAware` to receive the session `contextUser`+`provider`, reads a per-session `mediaCollectionID` override out of `RealtimeChannelServerContext.AgentSessionConfig` (the persisted `AIAgentSession.Config_`), and feeds the model a manifest via `SendContextNote`. The kit-resolution logic is the pure, unit-tested `agent-media-library.ts` (`buildAgentMediaContextNote` / `resolveAgentMediaManifest` / `formatAgentMediaManifest`); precedence is `runtime override > AIAgent.DefaultMediaCollectionID > none`. The agent then surfaces items with the existing `Media_ShowMedia` client tool — no new client tool. `LoadMediaChannelServer()` is invoked from MJServer's `agentSessions` module. See the [Real-Time Co-Agents Guide](../../../guides/REALTIME_CO_AGENTS_GUIDE.md).
|
|
193
201
|
- **`AgentMemoryContextBuilder`** (`src/agent-memory-context-builder.ts`) — the memory/RAG injection orchestration extracted out of `BaseAgent` so the co-agent assembles the **same** notes/examples/context a loop agent does, with no duplicated logic.
|
|
194
202
|
|
|
195
203
|
Delegated runs link to the co-agent's run via `ParentRunID` and share the session's `AgentSessionID`, so the whole episode — session, co-agent run (with its prompt run + Timeline step), delegated runs, transcript (`ConversationDetail` rows), channel state, usage telemetry (checkpointed server-side, or relayed from the browser via `RelayRealtimeUsage`) — groups under one session record with full standard observability.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Agent ('Agent' mode) reasoning provider for duplicate detection.
|
|
3
|
+
*
|
|
4
|
+
* Runs the shared "Duplicate Resolution" instruction set through an orchestrated agent
|
|
5
|
+
* (`AgentRunner.RunAgent`) rather than a single-shot prompt — the heavier path that unlocks
|
|
6
|
+
* memory-note injection and (Phase 2) context-exploration tools. It produces the IDENTICAL
|
|
7
|
+
* structured verdict as `PromptReasoningProvider` and persists the resulting `AIAgentRunID`.
|
|
8
|
+
*
|
|
9
|
+
* Lives in `@memberjunction/ai-agents` (not the dupe package) because the dupe package is a
|
|
10
|
+
* dependency of ai-agents — importing `AgentRunner` from there would create a build cycle.
|
|
11
|
+
* It registers against the abstract `DuplicateReasoningProvider` seam (defined in the dupe
|
|
12
|
+
* package) under the 'Agent' key, so the detector resolves it at runtime via ClassFactory
|
|
13
|
+
* with no static import back into the pipeline.
|
|
14
|
+
*
|
|
15
|
+
* @module @memberjunction/ai-agents
|
|
16
|
+
*/
|
|
17
|
+
import type { MJAIAgentEntityExtended } from '@memberjunction/ai-core-plus';
|
|
18
|
+
import { DuplicateReasoningProvider, DuplicateReasoningInput, DuplicateReasoningOutput, DuplicateReasoningContext } from '@memberjunction/ai-vector-dupe';
|
|
19
|
+
/**
|
|
20
|
+
* Agent-backed reasoning provider. Registered under the 'Agent' `ReasoningMode`.
|
|
21
|
+
*/
|
|
22
|
+
export declare class DuplicateReasoningAgentProvider extends DuplicateReasoningProvider {
|
|
23
|
+
/**
|
|
24
|
+
* Reason over a matched set via an orchestrated agent run.
|
|
25
|
+
*/
|
|
26
|
+
Reason(input: DuplicateReasoningInput, context: DuplicateReasoningContext): Promise<DuplicateReasoningOutput>;
|
|
27
|
+
/**
|
|
28
|
+
* Resolve the agent from `ReasoningAgentID`, falling back to the seeded
|
|
29
|
+
* "Duplicate Resolution Agent" by name. Uses the AIEngine cache (no DB query).
|
|
30
|
+
*/
|
|
31
|
+
protected resolveAgent(input: DuplicateReasoningInput): MJAIAgentEntityExtended | null;
|
|
32
|
+
/** Build params, run the agent, and translate the result into the reasoning contract. */
|
|
33
|
+
protected runAgent(agent: MJAIAgentEntityExtended, input: DuplicateReasoningInput, context: DuplicateReasoningContext): Promise<DuplicateReasoningOutput>;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=DuplicateReasoningAgentProvider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DuplicateReasoningAgentProvider.d.ts","sourceRoot":"","sources":["../src/DuplicateReasoningAgentProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAMH,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAC5E,OAAO,EACH,0BAA0B,EAE1B,uBAAuB,EACvB,wBAAwB,EACxB,yBAAyB,EAC5B,MAAM,gCAAgC,CAAC;AAMxC;;GAEG;AACH,qBACa,+BAAgC,SAAQ,0BAA0B;IAC3E;;OAEG;IACU,MAAM,CACf,KAAK,EAAE,uBAAuB,EAC9B,OAAO,EAAE,yBAAyB,GACnC,OAAO,CAAC,wBAAwB,CAAC;IAgBpC;;;OAGG;IACH,SAAS,CAAC,YAAY,CAAC,KAAK,EAAE,uBAAuB,GAAG,uBAAuB,GAAG,IAAI;IAYtF,yFAAyF;cACzE,QAAQ,CACpB,KAAK,EAAE,uBAAuB,EAC9B,KAAK,EAAE,uBAAuB,EAC9B,OAAO,EAAE,yBAAyB,GACnC,OAAO,CAAC,wBAAwB,CAAC;CA0BvC"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Agent ('Agent' mode) reasoning provider for duplicate detection.
|
|
3
|
+
*
|
|
4
|
+
* Runs the shared "Duplicate Resolution" instruction set through an orchestrated agent
|
|
5
|
+
* (`AgentRunner.RunAgent`) rather than a single-shot prompt — the heavier path that unlocks
|
|
6
|
+
* memory-note injection and (Phase 2) context-exploration tools. It produces the IDENTICAL
|
|
7
|
+
* structured verdict as `PromptReasoningProvider` and persists the resulting `AIAgentRunID`.
|
|
8
|
+
*
|
|
9
|
+
* Lives in `@memberjunction/ai-agents` (not the dupe package) because the dupe package is a
|
|
10
|
+
* dependency of ai-agents — importing `AgentRunner` from there would create a build cycle.
|
|
11
|
+
* It registers against the abstract `DuplicateReasoningProvider` seam (defined in the dupe
|
|
12
|
+
* package) under the 'Agent' key, so the detector resolves it at runtime via ClassFactory
|
|
13
|
+
* with no static import back into the pipeline.
|
|
14
|
+
*
|
|
15
|
+
* @module @memberjunction/ai-agents
|
|
16
|
+
*/
|
|
17
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
18
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
19
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
20
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
21
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
22
|
+
};
|
|
23
|
+
import { LogError } from '@memberjunction/core';
|
|
24
|
+
import { RegisterClass, UUIDsEqual } from '@memberjunction/global';
|
|
25
|
+
import { AIEngine } from '@memberjunction/aiengine';
|
|
26
|
+
import { DuplicateReasoningProvider, AGENT_REASONING_PROVIDER_KEY, } from '@memberjunction/ai-vector-dupe';
|
|
27
|
+
import { AgentRunner } from './AgentRunner.js';
|
|
28
|
+
/** The name of the seeded agent used when an Entity Document doesn't specify one. */
|
|
29
|
+
const DEFAULT_REASONING_AGENT_NAME = 'Duplicate Resolution Agent';
|
|
30
|
+
/**
|
|
31
|
+
* Agent-backed reasoning provider. Registered under the 'Agent' `ReasoningMode`.
|
|
32
|
+
*/
|
|
33
|
+
let DuplicateReasoningAgentProvider = class DuplicateReasoningAgentProvider extends DuplicateReasoningProvider {
|
|
34
|
+
/**
|
|
35
|
+
* Reason over a matched set via an orchestrated agent run.
|
|
36
|
+
*/
|
|
37
|
+
async Reason(input, context) {
|
|
38
|
+
try {
|
|
39
|
+
await AIEngine.Instance.Config(false, context.ContextUser, context.Provider);
|
|
40
|
+
const agent = this.resolveAgent(input);
|
|
41
|
+
if (!agent) {
|
|
42
|
+
return this.failedOutput(`No reasoning agent resolved (ReasoningAgentID=${input.EntityDocument.ReasoningAgentID ?? 'null'}, fallback="${DEFAULT_REASONING_AGENT_NAME}")`);
|
|
43
|
+
}
|
|
44
|
+
return await this.runAgent(agent, input, context);
|
|
45
|
+
}
|
|
46
|
+
catch (e) {
|
|
47
|
+
LogError(e);
|
|
48
|
+
return this.failedOutput(e instanceof Error ? e.message : String(e));
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Resolve the agent from `ReasoningAgentID`, falling back to the seeded
|
|
53
|
+
* "Duplicate Resolution Agent" by name. Uses the AIEngine cache (no DB query).
|
|
54
|
+
*/
|
|
55
|
+
resolveAgent(input) {
|
|
56
|
+
const agents = AIEngine.Instance.Agents;
|
|
57
|
+
const agentId = input.EntityDocument.ReasoningAgentID;
|
|
58
|
+
if (agentId) {
|
|
59
|
+
const byId = agents.find(a => UUIDsEqual(a.ID, agentId));
|
|
60
|
+
if (byId) {
|
|
61
|
+
return byId;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return agents.find(a => a.Name === DEFAULT_REASONING_AGENT_NAME) ?? null;
|
|
65
|
+
}
|
|
66
|
+
/** Build params, run the agent, and translate the result into the reasoning contract. */
|
|
67
|
+
async runAgent(agent, input, context) {
|
|
68
|
+
const messages = [{
|
|
69
|
+
role: 'user',
|
|
70
|
+
content: 'Reason over the supplied source record and candidate matches and return the structured duplicate-resolution verdict.',
|
|
71
|
+
}];
|
|
72
|
+
const runner = new AgentRunner(context.Provider);
|
|
73
|
+
const result = await runner.RunAgent({
|
|
74
|
+
agent,
|
|
75
|
+
conversationMessages: messages,
|
|
76
|
+
contextUser: context.ContextUser,
|
|
77
|
+
// The shared instruction template reads these as its data context.
|
|
78
|
+
data: this.buildPromptData(input),
|
|
79
|
+
});
|
|
80
|
+
const agentRunID = result.agentRun?.ID ?? null;
|
|
81
|
+
if (!result.success) {
|
|
82
|
+
const failed = this.failedOutput(result.agentRun?.ErrorMessage ?? 'Agent execution failed');
|
|
83
|
+
failed.AIAgentRunID = agentRunID;
|
|
84
|
+
return failed;
|
|
85
|
+
}
|
|
86
|
+
const output = this.parseRawOutput(result.payload);
|
|
87
|
+
output.AIAgentRunID = agentRunID;
|
|
88
|
+
return output;
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
DuplicateReasoningAgentProvider = __decorate([
|
|
92
|
+
RegisterClass(DuplicateReasoningProvider, AGENT_REASONING_PROVIDER_KEY)
|
|
93
|
+
], DuplicateReasoningAgentProvider);
|
|
94
|
+
export { DuplicateReasoningAgentProvider };
|
|
95
|
+
//# sourceMappingURL=DuplicateReasoningAgentProvider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DuplicateReasoningAgentProvider.js","sourceRoot":"","sources":["../src/DuplicateReasoningAgentProvider.ts"],"names":[],"mappings":"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"}
|
|
@@ -21,6 +21,13 @@ export declare class MJAIAgentRequestEntityServer extends MJAIAgentRequestEntity
|
|
|
21
21
|
* run via AgentRunner. Then update this request with the new run's ID.
|
|
22
22
|
*/
|
|
23
23
|
private resumeAgent;
|
|
24
|
+
/**
|
|
25
|
+
* Returns true when this request originated from a Plan Mode 'Plan' run-step, meaning the
|
|
26
|
+
* resumed run should re-enable plan mode (so approved-vs-rejected is honored). Fails safe to
|
|
27
|
+
* false (regular resume, plan mode off) if the originating step can't be loaded — the worst case
|
|
28
|
+
* is that an approved plan proceeds, which is the desired outcome anyway.
|
|
29
|
+
*/
|
|
30
|
+
private isPlanStepResume;
|
|
24
31
|
/**
|
|
25
32
|
* Build a conversation message from the structured ResponseData and
|
|
26
33
|
* free-text Response fields. Uses the @{_mode:"form",...} token format
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MJAIAgentRequestEntityServer.d.ts","sourceRoot":"","sources":["../src/MJAIAgentRequestEntityServer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAc,iBAAiB,EAAoD,MAAM,sBAAsB,CAAC;AAEvH,OAAO,EAAE,sBAAsB,
|
|
1
|
+
{"version":3,"file":"MJAIAgentRequestEntityServer.d.ts","sourceRoot":"","sources":["../src/MJAIAgentRequestEntityServer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAc,iBAAiB,EAAoD,MAAM,sBAAsB,CAAC;AAEvH,OAAO,EAAE,sBAAsB,EAA8C,MAAM,+BAA+B,CAAC;AAQnH,qBACa,4BAA6B,SAAQ,sBAAsB;IACrD,IAAI,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC;IA6BlE;;;OAGG;YACW,WAAW;IA4EzB;;;;;OAKG;YACW,gBAAgB;IAY9B;;;;;;;OAOG;IACH,OAAO,CAAC,kBAAkB;IAwC1B;;;OAGG;IACH,OAAO,CAAC,uBAAuB;IA6B/B,sFAAsF;IACtF,OAAO,CAAC,mBAAmB;IAS3B,6CAA6C;IAC7C,OAAO,CAAC,gBAAgB;IAIxB,+EAA+E;IAC/E,OAAO,CAAC,kBAAkB;CAS7B"}
|
|
@@ -82,6 +82,12 @@ let MJAIAgentRequestEntityServer = class MJAIAgentRequestEntityServer extends MJ
|
|
|
82
82
|
content: userMessage
|
|
83
83
|
});
|
|
84
84
|
}
|
|
85
|
+
// Plan Mode resumes must re-enable plan mode so the framework's gate re-engages and can
|
|
86
|
+
// distinguish an approved plan (proceed) from a rejected one (present a revised plan). Only
|
|
87
|
+
// do this when the request originated from a 'Plan' run-step — regular Chat-clarification
|
|
88
|
+
// resumes stay exactly as they were (planMode left undefined). resolvePlanModeGate then reads
|
|
89
|
+
// this run's request status to decide approved-vs-rejected; see base-agent.ts.
|
|
90
|
+
const isPlanResume = await this.isPlanStepResume(md, contextUser);
|
|
85
91
|
// Run the agent with lastRunId to continue the conversation
|
|
86
92
|
const runner = new AgentRunner();
|
|
87
93
|
const params = {
|
|
@@ -89,7 +95,8 @@ let MJAIAgentRequestEntityServer = class MJAIAgentRequestEntityServer extends MJ
|
|
|
89
95
|
conversationMessages,
|
|
90
96
|
contextUser,
|
|
91
97
|
lastRunId: this.OriginatingAgentRunID,
|
|
92
|
-
autoPopulateLastRunPayload: true
|
|
98
|
+
autoPopulateLastRunPayload: true,
|
|
99
|
+
...(isPlanResume ? { planMode: true } : {})
|
|
93
100
|
};
|
|
94
101
|
LogStatus(`🔄 Resuming agent "${agentEntity.Name}" for feedback request ${this.ID}`);
|
|
95
102
|
const result = await runner.RunAgentInConversation(params, {
|
|
@@ -108,6 +115,26 @@ let MJAIAgentRequestEntityServer = class MJAIAgentRequestEntityServer extends MJ
|
|
|
108
115
|
}
|
|
109
116
|
}
|
|
110
117
|
}
|
|
118
|
+
/**
|
|
119
|
+
* Returns true when this request originated from a Plan Mode 'Plan' run-step, meaning the
|
|
120
|
+
* resumed run should re-enable plan mode (so approved-vs-rejected is honored). Fails safe to
|
|
121
|
+
* false (regular resume, plan mode off) if the originating step can't be loaded — the worst case
|
|
122
|
+
* is that an approved plan proceeds, which is the desired outcome anyway.
|
|
123
|
+
*/
|
|
124
|
+
async isPlanStepResume(md, contextUser) {
|
|
125
|
+
if (!this.OriginatingAgentRunStepID)
|
|
126
|
+
return false;
|
|
127
|
+
try {
|
|
128
|
+
const step = await md.GetEntityObject('MJ: AI Agent Run Steps', contextUser);
|
|
129
|
+
if (!(await step.Load(this.OriginatingAgentRunStepID)))
|
|
130
|
+
return false;
|
|
131
|
+
return step.StepType === 'Plan';
|
|
132
|
+
}
|
|
133
|
+
catch (error) {
|
|
134
|
+
LogError(`isPlanStepResume: failed to load originating step ${this.OriginatingAgentRunStepID}: ${error.message}`);
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
111
138
|
/**
|
|
112
139
|
* Build a conversation message from the structured ResponseData and
|
|
113
140
|
* free-text Response fields. Uses the @{_mode:"form",...} token format
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MJAIAgentRequestEntityServer.js","sourceRoot":"","sources":["../src/MJAIAgentRequestEntityServer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;;;;;;;AAEH,OAAO,EAAE,UAAU,EAAqB,QAAQ,EAAE,SAAS,EAA+B,MAAM,sBAAsB,CAAC;AACvH,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,sBAAsB,
|
|
1
|
+
{"version":3,"file":"MJAIAgentRequestEntityServer.js","sourceRoot":"","sources":["../src/MJAIAgentRequestEntityServer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Orchestrates SKILL.md export/import against the database: resolves Action/Agent
|
|
3
|
+
* names to IDs (import) and IDs back to names (export), and creates/updates the MJ: AI Skills +
|
|
4
|
+
* junction entities. Builds on the pure {@link SkillMarkdownConverter} for the text<->data
|
|
5
|
+
* transformation itself.
|
|
6
|
+
*
|
|
7
|
+
* @module @memberjunction/ai-agents
|
|
8
|
+
*/
|
|
9
|
+
import { IMetadataProvider, UserInfo } from '@memberjunction/core';
|
|
10
|
+
import { MJAISkillEntity } from '@memberjunction/core-entities';
|
|
11
|
+
/**
|
|
12
|
+
* Options for {@link SkillImportExportService.ImportSkill}.
|
|
13
|
+
*/
|
|
14
|
+
export interface ImportSkillOptions {
|
|
15
|
+
/**
|
|
16
|
+
* When provided, updates this existing skill (and resyncs its Action/sub-agent bundling)
|
|
17
|
+
* instead of creating a new one. The caller is responsible for confirming the current user is
|
|
18
|
+
* allowed to edit this skill (e.g. it's their own, per the "own skills" RLS filter).
|
|
19
|
+
*/
|
|
20
|
+
updateSkillId?: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Result of {@link SkillImportExportService.ImportSkill}.
|
|
24
|
+
*/
|
|
25
|
+
export interface ImportSkillResult {
|
|
26
|
+
skill: MJAISkillEntity;
|
|
27
|
+
/** Action/sub-agent names from the SKILL.md that couldn't be resolved — the skill is still
|
|
28
|
+
* created/updated with whatever DID resolve, so the caller can surface these as non-fatal
|
|
29
|
+
* warnings rather than failing the whole import. */
|
|
30
|
+
warnings: string[];
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Result of {@link SkillImportExportService.ExportSkill}.
|
|
34
|
+
*/
|
|
35
|
+
export interface ExportSkillResult {
|
|
36
|
+
markdown: string;
|
|
37
|
+
/** The skill's Name — returned alongside the markdown so callers don't need a second load. */
|
|
38
|
+
skillName: string;
|
|
39
|
+
}
|
|
40
|
+
export declare class SkillImportExportService {
|
|
41
|
+
/**
|
|
42
|
+
* Exports a skill to a portable SKILL.md string: Action/sub-agent IDs are resolved to their
|
|
43
|
+
* current Names (not IDs, for cross-instance portability) via the AI/Action engine caches.
|
|
44
|
+
*/
|
|
45
|
+
static ExportSkill(skillId: string, contextUser: UserInfo, provider?: IMetadataProvider): Promise<ExportSkillResult>;
|
|
46
|
+
/**
|
|
47
|
+
* Imports a SKILL.md document, resolving Action/sub-agent names against the current instance's
|
|
48
|
+
* catalog (unresolvable names are dropped and reported as warnings, not fatal errors — a skill
|
|
49
|
+
* authored against a different MJ instance may reference actions that don't exist here yet).
|
|
50
|
+
*/
|
|
51
|
+
static ImportSkill(markdownText: string, contextUser: UserInfo, options?: ImportSkillOptions, provider?: IMetadataProvider): Promise<ImportSkillResult>;
|
|
52
|
+
/**
|
|
53
|
+
* Loads the AI + Action engine caches that name/ID resolution depends on. Both `Config()` calls
|
|
54
|
+
* are idempotent — a no-op when the engine is already loaded (the common server case) — so this
|
|
55
|
+
* is cheap insurance against a cold caller producing empty resolutions.
|
|
56
|
+
*/
|
|
57
|
+
private static ensureEnginesConfigured;
|
|
58
|
+
/** Resolves a list of names against a cached entity array (by ID+Name), collecting a warning for each miss. */
|
|
59
|
+
private static resolveNames;
|
|
60
|
+
/** Deletes existing junction rows for the skill and recreates them from the resolved ID set — the simplest correct resync for a small bounded set of rows. */
|
|
61
|
+
private static resyncJunction;
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=SkillImportExportService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SkillImportExportService.d.ts","sourceRoot":"","sources":["../src/SkillImportExportService.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,iBAAiB,EAAqB,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAEtF,OAAO,EAAE,eAAe,EAAkD,MAAM,+BAA+B,CAAC;AAKhH;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAC/B;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAC9B,KAAK,EAAE,eAAe,CAAC;IACvB;;yDAEqD;IACrD,QAAQ,EAAE,MAAM,EAAE,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,8FAA8F;IAC9F,SAAS,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,wBAAwB;IACjC;;;OAGG;WACiB,WAAW,CAC3B,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,QAAQ,EACrB,QAAQ,CAAC,EAAE,iBAAiB,GAC7B,OAAO,CAAC,iBAAiB,CAAC;IA6C7B;;;;OAIG;WACiB,WAAW,CAC3B,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,QAAQ,EACrB,OAAO,CAAC,EAAE,kBAAkB,EAC5B,QAAQ,CAAC,EAAE,iBAAiB,GAC7B,OAAO,CAAC,iBAAiB,CAAC;IAiD7B;;;;OAIG;mBACkB,uBAAuB;IAK5C,+GAA+G;IAC/G,OAAO,CAAC,MAAM,CAAC,YAAY;IAkB3B,8JAA8J;mBACzI,cAAc;CAmCtC"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Orchestrates SKILL.md export/import against the database: resolves Action/Agent
|
|
3
|
+
* names to IDs (import) and IDs back to names (export), and creates/updates the MJ: AI Skills +
|
|
4
|
+
* junction entities. Builds on the pure {@link SkillMarkdownConverter} for the text<->data
|
|
5
|
+
* transformation itself.
|
|
6
|
+
*
|
|
7
|
+
* @module @memberjunction/ai-agents
|
|
8
|
+
*/
|
|
9
|
+
import { Metadata, RunView } from '@memberjunction/core';
|
|
10
|
+
import { UUIDsEqual } from '@memberjunction/global';
|
|
11
|
+
import { AIEngine } from '@memberjunction/aiengine';
|
|
12
|
+
import { ActionEngineServer } from '@memberjunction/actions';
|
|
13
|
+
import { SkillMarkdownConverter } from './SkillMarkdownConverter.js';
|
|
14
|
+
export class SkillImportExportService {
|
|
15
|
+
/**
|
|
16
|
+
* Exports a skill to a portable SKILL.md string: Action/sub-agent IDs are resolved to their
|
|
17
|
+
* current Names (not IDs, for cross-instance portability) via the AI/Action engine caches.
|
|
18
|
+
*/
|
|
19
|
+
static async ExportSkill(skillId, contextUser, provider) {
|
|
20
|
+
const md = provider ?? Metadata.Provider;
|
|
21
|
+
// Name resolution below reads the AI/Action engine caches — ensure they're loaded (idempotent
|
|
22
|
+
// no-op when already configured). Without this, a cold caller resolves every ID to no name.
|
|
23
|
+
await this.ensureEnginesConfigured(contextUser, md);
|
|
24
|
+
const skill = await md.GetEntityObject('MJ: AI Skills', contextUser);
|
|
25
|
+
const loaded = await skill.Load(skillId);
|
|
26
|
+
if (!loaded) {
|
|
27
|
+
throw new Error(`Skill ${skillId} not found`);
|
|
28
|
+
}
|
|
29
|
+
const rv = new RunView();
|
|
30
|
+
const [actionRows, subAgentRows] = await rv.RunViews([
|
|
31
|
+
{
|
|
32
|
+
EntityName: 'MJ: AI Skill Actions',
|
|
33
|
+
ExtraFilter: `SkillID='${skillId}'`,
|
|
34
|
+
ResultType: 'simple'
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
EntityName: 'MJ: AI Skill Sub Agents',
|
|
38
|
+
ExtraFilter: `SkillID='${skillId}'`,
|
|
39
|
+
ResultType: 'simple'
|
|
40
|
+
}
|
|
41
|
+
], contextUser);
|
|
42
|
+
const actionNames = (actionRows.Success ? actionRows.Results : [])
|
|
43
|
+
.map(row => ActionEngineServer.Instance.Actions.find(a => UUIDsEqual(a.ID, row.ActionID))?.Name)
|
|
44
|
+
.filter((name) => !!name);
|
|
45
|
+
const subAgentNames = (subAgentRows.Success ? subAgentRows.Results : [])
|
|
46
|
+
.map(row => AIEngine.Instance.Agents.find(a => UUIDsEqual(a.ID, row.SubAgentID))?.Name)
|
|
47
|
+
.filter((name) => !!name);
|
|
48
|
+
const markdown = SkillMarkdownConverter.Serialize({
|
|
49
|
+
name: skill.Name,
|
|
50
|
+
description: skill.Description ?? undefined,
|
|
51
|
+
category: skill.Category ?? undefined,
|
|
52
|
+
actionNames,
|
|
53
|
+
subAgentNames,
|
|
54
|
+
instructions: skill.Instructions
|
|
55
|
+
});
|
|
56
|
+
return { markdown, skillName: skill.Name };
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Imports a SKILL.md document, resolving Action/sub-agent names against the current instance's
|
|
60
|
+
* catalog (unresolvable names are dropped and reported as warnings, not fatal errors — a skill
|
|
61
|
+
* authored against a different MJ instance may reference actions that don't exist here yet).
|
|
62
|
+
*/
|
|
63
|
+
static async ImportSkill(markdownText, contextUser, options, provider) {
|
|
64
|
+
const parsed = SkillMarkdownConverter.Parse(markdownText);
|
|
65
|
+
const warnings = [];
|
|
66
|
+
const md = provider ?? Metadata.Provider;
|
|
67
|
+
// Name→ID resolution below reads the AI/Action engine caches — ensure they're loaded
|
|
68
|
+
// (idempotent). Without this, every bundled Action/sub-agent name would falsely resolve to a
|
|
69
|
+
// "not found" warning on a cold server.
|
|
70
|
+
await this.ensureEnginesConfigured(contextUser, md);
|
|
71
|
+
const resolvedActionIDs = this.resolveNames(parsed.frontmatter.actions ?? [], ActionEngineServer.Instance.Actions, warnings, 'Action');
|
|
72
|
+
const resolvedSubAgentIDs = this.resolveNames(parsed.frontmatter.subAgents ?? [], AIEngine.Instance.Agents, warnings, 'Sub-agent');
|
|
73
|
+
const skill = await md.GetEntityObject('MJ: AI Skills', contextUser);
|
|
74
|
+
if (options?.updateSkillId) {
|
|
75
|
+
const loaded = await skill.Load(options.updateSkillId);
|
|
76
|
+
if (!loaded) {
|
|
77
|
+
throw new Error(`Skill ${options.updateSkillId} not found for update`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
skill.NewRecord();
|
|
82
|
+
skill.CreatedByUserID = contextUser.ID;
|
|
83
|
+
skill.Status = 'Active';
|
|
84
|
+
}
|
|
85
|
+
skill.Name = parsed.frontmatter.name;
|
|
86
|
+
skill.Description = parsed.frontmatter.description ?? null;
|
|
87
|
+
skill.Category = parsed.frontmatter.category ?? null;
|
|
88
|
+
skill.Instructions = parsed.instructions;
|
|
89
|
+
const saved = await skill.Save();
|
|
90
|
+
if (!saved) {
|
|
91
|
+
throw new Error(`Failed to save imported skill: ${skill.LatestResult?.CompleteMessage ?? 'unknown error'}`);
|
|
92
|
+
}
|
|
93
|
+
await this.resyncJunction(skill.ID, 'MJ: AI Skill Actions', resolvedActionIDs, 'ActionID', contextUser, md);
|
|
94
|
+
await this.resyncJunction(skill.ID, 'MJ: AI Skill Sub Agents', resolvedSubAgentIDs, 'SubAgentID', contextUser, md);
|
|
95
|
+
return { skill, warnings };
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Loads the AI + Action engine caches that name/ID resolution depends on. Both `Config()` calls
|
|
99
|
+
* are idempotent — a no-op when the engine is already loaded (the common server case) — so this
|
|
100
|
+
* is cheap insurance against a cold caller producing empty resolutions.
|
|
101
|
+
*/
|
|
102
|
+
static async ensureEnginesConfigured(contextUser, provider) {
|
|
103
|
+
await AIEngine.Instance.Config(false, contextUser, provider);
|
|
104
|
+
await ActionEngineServer.Instance.Config(false, contextUser, provider);
|
|
105
|
+
}
|
|
106
|
+
/** Resolves a list of names against a cached entity array (by ID+Name), collecting a warning for each miss. */
|
|
107
|
+
static resolveNames(names, catalog, warnings, kindLabel) {
|
|
108
|
+
const resolved = [];
|
|
109
|
+
for (const name of names) {
|
|
110
|
+
const match = catalog.find(c => c.Name.trim().toLowerCase() === name.trim().toLowerCase());
|
|
111
|
+
if (match) {
|
|
112
|
+
resolved.push(match.ID);
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
warnings.push(`${kindLabel} '${name}' not found in this instance — skipped`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return resolved;
|
|
119
|
+
}
|
|
120
|
+
/** Deletes existing junction rows for the skill and recreates them from the resolved ID set — the simplest correct resync for a small bounded set of rows. */
|
|
121
|
+
static async resyncJunction(skillId, entityName, resolvedIDs, idFieldName, contextUser, provider) {
|
|
122
|
+
const rv = new RunView();
|
|
123
|
+
const existing = await rv.RunView({
|
|
124
|
+
EntityName: entityName,
|
|
125
|
+
ExtraFilter: `SkillID='${skillId}'`,
|
|
126
|
+
ResultType: 'entity_object'
|
|
127
|
+
}, contextUser);
|
|
128
|
+
if (existing.Success) {
|
|
129
|
+
for (const row of existing.Results) {
|
|
130
|
+
const deleted = await row.Delete();
|
|
131
|
+
if (!deleted) {
|
|
132
|
+
throw new Error(`Failed to remove existing ${entityName} row during skill re-sync: ${row.LatestResult?.CompleteMessage ?? 'unknown error'}`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
for (const id of resolvedIDs) {
|
|
137
|
+
const junctionRow = await provider.GetEntityObject(entityName, contextUser);
|
|
138
|
+
junctionRow.NewRecord();
|
|
139
|
+
junctionRow.SkillID = skillId;
|
|
140
|
+
junctionRow[idFieldName] = id;
|
|
141
|
+
const saved = await junctionRow.Save();
|
|
142
|
+
if (!saved) {
|
|
143
|
+
throw new Error(`Failed to create ${entityName} row during skill re-sync: ${junctionRow.LatestResult?.CompleteMessage ?? 'unknown error'}`);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=SkillImportExportService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SkillImportExportService.js","sourceRoot":"","sources":["../src/SkillImportExportService.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Pure parse/serialize for the portable SKILL.md format — no database or engine
|
|
3
|
+
* dependency, so this is fully unit-testable in isolation. `SkillImportExportService` builds on
|
|
4
|
+
* top of this to do the actual name<->ID resolution and entity persistence.
|
|
5
|
+
*
|
|
6
|
+
* ## Format
|
|
7
|
+
* ```markdown
|
|
8
|
+
* ---
|
|
9
|
+
* name: Report Builder
|
|
10
|
+
* description: Generates formatted business reports from query results
|
|
11
|
+
* category: Reporting
|
|
12
|
+
* actions:
|
|
13
|
+
* - Run Query
|
|
14
|
+
* - Generate PDF
|
|
15
|
+
* subAgents:
|
|
16
|
+
* - Report Formatter Agent
|
|
17
|
+
* ---
|
|
18
|
+
*
|
|
19
|
+
* Instructions body — plain markdown, appended to an accepting agent's system
|
|
20
|
+
* prompt when the skill is activated.
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* Deliberately NOT a general-purpose YAML parser — the frontmatter shape is fixed and small
|
|
24
|
+
* (flat scalar keys + simple string-list keys), so a hand-rolled parser avoids taking on a new
|
|
25
|
+
* dependency for a narrow, fully-controlled need.
|
|
26
|
+
*
|
|
27
|
+
* @module @memberjunction/ai-agents
|
|
28
|
+
*/
|
|
29
|
+
/**
|
|
30
|
+
* The frontmatter fields of a SKILL.md file. `actions`/`subAgents` are Action/Agent NAMES (not
|
|
31
|
+
* IDs) — portability across MJ instances means names are the only stable cross-instance
|
|
32
|
+
* reference; ID resolution happens at import time via {@link SkillImportExportService}.
|
|
33
|
+
*/
|
|
34
|
+
export interface SkillMarkdownFrontmatter {
|
|
35
|
+
name: string;
|
|
36
|
+
description?: string;
|
|
37
|
+
category?: string;
|
|
38
|
+
actions?: string[];
|
|
39
|
+
subAgents?: string[];
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Result of parsing a SKILL.md file: the frontmatter fields plus the Instructions body.
|
|
43
|
+
*/
|
|
44
|
+
export interface ParsedSkillMarkdown {
|
|
45
|
+
frontmatter: SkillMarkdownFrontmatter;
|
|
46
|
+
instructions: string;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Inputs to {@link SkillMarkdownConverter.Serialize} — the export-side counterpart of
|
|
50
|
+
* {@link ParsedSkillMarkdown}, using resolved names (not IDs) for portability.
|
|
51
|
+
*/
|
|
52
|
+
export interface SerializeSkillMarkdownParams {
|
|
53
|
+
name: string;
|
|
54
|
+
description?: string;
|
|
55
|
+
category?: string;
|
|
56
|
+
actionNames?: string[];
|
|
57
|
+
subAgentNames?: string[];
|
|
58
|
+
instructions: string;
|
|
59
|
+
}
|
|
60
|
+
export declare class SkillMarkdownConverter {
|
|
61
|
+
/**
|
|
62
|
+
* Parses a SKILL.md document into its frontmatter + instructions body. Throws with a clear
|
|
63
|
+
* message on malformed input (missing/unterminated frontmatter block, missing required `name`).
|
|
64
|
+
*/
|
|
65
|
+
static Parse(markdownText: string): ParsedSkillMarkdown;
|
|
66
|
+
/**
|
|
67
|
+
* Serializes skill data into a SKILL.md document. The inverse of {@link Parse}.
|
|
68
|
+
*/
|
|
69
|
+
static Serialize(params: SerializeSkillMarkdownParams): string;
|
|
70
|
+
/**
|
|
71
|
+
* Parses the frontmatter line block into a {@link SkillMarkdownFrontmatter}. Supports flat
|
|
72
|
+
* `key: value` scalars and `key:` followed by ` - item` list entries — nothing more complex
|
|
73
|
+
* (no nested objects, no multiline scalars). Unknown keys are ignored rather than erroring, so
|
|
74
|
+
* a future field addition doesn't break parsing of older SKILL.md files.
|
|
75
|
+
*/
|
|
76
|
+
private static parseFrontmatterLines;
|
|
77
|
+
/** Quotes a scalar value if it contains a colon or leading/trailing whitespace that would otherwise break the simple parser. */
|
|
78
|
+
private static escapeScalar;
|
|
79
|
+
/** Strips the quoting {@link escapeScalar} applies, if present. */
|
|
80
|
+
private static unescapeScalar;
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=SkillMarkdownConverter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SkillMarkdownConverter.d.ts","sourceRoot":"","sources":["../src/SkillMarkdownConverter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH;;;;GAIG;AACH,MAAM,WAAW,wBAAwB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAChC,WAAW,EAAE,wBAAwB,CAAC;IACtC,YAAY,EAAE,MAAM,CAAC;CACxB;AAED;;;GAGG;AACH,MAAM,WAAW,4BAA4B;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;CACxB;AAID,qBAAa,sBAAsB;IAC/B;;;OAGG;WACW,KAAK,CAAC,YAAY,EAAE,MAAM,GAAG,mBAAmB;IA2B9D;;OAEG;WACW,SAAS,CAAC,MAAM,EAAE,4BAA4B,GAAG,MAAM;IA6BrE;;;;;OAKG;IACH,OAAO,CAAC,MAAM,CAAC,qBAAqB;IA6CpC,gIAAgI;IAChI,OAAO,CAAC,MAAM,CAAC,YAAY;IAO3B,mEAAmE;IACnE,OAAO,CAAC,MAAM,CAAC,cAAc;CAOhC"}
|