forked from EduCraft/curriculum-project-hub
feat: add curated curriculum agent skills
This commit is contained in:
+14
-1
@@ -29,7 +29,7 @@
|
||||
* `workspace.ts` `confine()` path validator as a tool wrapper — the OS sandbox
|
||||
* is the mechanism, the contract pins the invariant.
|
||||
*/
|
||||
import { query, type HookCallback, type McpServerConfig, type SDKMessage, type SDKAssistantMessage, type SDKUserMessage, type SDKResultMessage, type SDKPartialAssistantMessage } from "@anthropic-ai/claude-agent-sdk";
|
||||
import { query, type HookCallback, type McpServerConfig, type SDKMessage, type SDKAssistantMessage, type SDKUserMessage, type SDKResultMessage, type SDKPartialAssistantMessage, type SDKSystemMessage } from "@anthropic-ai/claude-agent-sdk";
|
||||
import type { PrismaClient } from "@prisma/client";
|
||||
import { claudeSdkToolConfigForRole } from "./roleTools.js";
|
||||
import { createAgentSecurityPolicy } from "./security.js";
|
||||
@@ -91,6 +91,8 @@ export interface RunResult {
|
||||
readonly costUsd?: number | undefined;
|
||||
readonly numTurns: number;
|
||||
readonly sdkSessionId?: string | undefined;
|
||||
/** Skill ids reported by the SDK init event, not merely requested options. */
|
||||
readonly initializedSkillIds?: readonly string[] | undefined;
|
||||
readonly error?: string;
|
||||
}
|
||||
|
||||
@@ -131,6 +133,7 @@ export async function runAgent(req: RunRequest): Promise<RunResult> {
|
||||
let costUsd: number | undefined;
|
||||
let numTurns = 0;
|
||||
let sdkSessionId: string | undefined;
|
||||
let initializedSkillIds: readonly string[] | undefined;
|
||||
let error: string | undefined;
|
||||
try {
|
||||
await persistAgentMessage(req, "user", req.prompt);
|
||||
@@ -166,6 +169,8 @@ export async function runAgent(req: RunRequest): Promise<RunResult> {
|
||||
// The project workspace is untrusted input. Do not load user/project
|
||||
// settings that could widen tools, hooks, MCP servers, or sandbox paths.
|
||||
settingSources: [],
|
||||
plugins: [{ type: "local", path: security.skillPluginRoot, skipMcpDiscovery: true }],
|
||||
skills: [...security.skillIds],
|
||||
strictMcpConfig: true,
|
||||
// Claude Code 2.1.202 can honor the per-call opt-out despite
|
||||
// sandbox.allowUnsandboxedCommands=false. Enforce the invariant again at
|
||||
@@ -191,6 +196,12 @@ export async function runAgent(req: RunRequest): Promise<RunResult> {
|
||||
|
||||
for await (const message of conversation) {
|
||||
switch (message.type) {
|
||||
case "system": {
|
||||
if (message.subtype === "init") {
|
||||
initializedSkillIds = [...(message as SDKSystemMessage).skills];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "stream_event": {
|
||||
const evt = (message as SDKPartialAssistantMessage).event;
|
||||
if (evt.type === "content_block_delta" && evt.delta.type === "text_delta") {
|
||||
@@ -287,6 +298,7 @@ export async function runAgent(req: RunRequest): Promise<RunResult> {
|
||||
...(costUsd !== undefined ? { costUsd } : {}),
|
||||
numTurns,
|
||||
sdkSessionId,
|
||||
...(initializedSkillIds !== undefined ? { initializedSkillIds } : {}),
|
||||
...(error !== undefined ? { error } : {}),
|
||||
};
|
||||
} catch (e) {
|
||||
@@ -298,6 +310,7 @@ export async function runAgent(req: RunRequest): Promise<RunResult> {
|
||||
...(costUsd !== undefined ? { costUsd } : {}),
|
||||
numTurns,
|
||||
sdkSessionId,
|
||||
...(initializedSkillIds !== undefined ? { initializedSkillIds } : {}),
|
||||
...(aborted ? {} : { error: e instanceof Error ? e.message : String(e) }),
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user