stageflow 0.27.0 → 0.31.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 +4 -0
- package/builtin-skills/browser/SKILL.md +42 -0
- package/dist/agent/claudeAdapter.js +2 -2
- package/dist/agent/cursorProvider.d.ts +10 -0
- package/dist/agent/cursorProvider.js +83 -8
- package/dist/agent/fakeAgent.d.ts +1 -0
- package/dist/agent/fakeAgent.js +13 -0
- package/dist/agent/piAdapter.d.ts +3 -24
- package/dist/agent/piAdapter.js +49 -47
- package/dist/agent/piSessionFactory.d.ts +38 -0
- package/dist/agent/piSessionFactory.js +60 -0
- package/dist/agent/port.d.ts +2 -0
- package/dist/agent/providerAuth.d.ts +7 -3
- package/dist/agent/providerAuth.js +5 -3
- package/dist/agent/streamLogRedact.d.ts +6 -0
- package/dist/agent/streamLogRedact.js +23 -1
- package/dist/browser/anchor.d.ts +27 -0
- package/dist/browser/anchor.js +127 -0
- package/dist/browser/auditSink.d.ts +38 -0
- package/dist/browser/auditSink.js +34 -0
- package/dist/browser/browserHost.d.ts +86 -0
- package/dist/browser/browserHost.js +7 -0
- package/dist/browser/browserSweep.d.ts +14 -0
- package/dist/browser/browserSweep.js +54 -0
- package/dist/browser/browserTeardown.d.ts +56 -0
- package/dist/browser/browserTeardown.js +235 -0
- package/dist/browser/fakeRemoteBrowserHost.d.ts +2 -0
- package/dist/browser/fakeRemoteBrowserHost.js +34 -0
- package/dist/browser/gateHandoff.d.ts +25 -0
- package/dist/browser/gateHandoff.js +83 -0
- package/dist/browser/humanLogin.d.ts +18 -0
- package/dist/browser/humanLogin.js +34 -0
- package/dist/browser/keyProvider.d.ts +10 -0
- package/dist/browser/keyProvider.js +39 -0
- package/dist/browser/localBrowserHost.d.ts +10 -0
- package/dist/browser/localBrowserHost.js +152 -0
- package/dist/browser/localProfileLock.d.ts +2 -0
- package/dist/browser/localProfileLock.js +218 -0
- package/dist/browser/localProfileStore.d.ts +5 -0
- package/dist/browser/localProfileStore.js +91 -0
- package/dist/browser/loginCheck.d.ts +53 -0
- package/dist/browser/loginCheck.js +147 -0
- package/dist/browser/memoryProfileLock.d.ts +2 -0
- package/dist/browser/memoryProfileLock.js +53 -0
- package/dist/browser/memoryProfileStore.d.ts +2 -0
- package/dist/browser/memoryProfileStore.js +31 -0
- package/dist/browser/navigationAudit.d.ts +16 -0
- package/dist/browser/navigationAudit.js +53 -0
- package/dist/browser/persistedEnv.d.ts +3 -0
- package/dist/browser/persistedEnv.js +15 -0
- package/dist/browser/profileLock.d.ts +40 -0
- package/dist/browser/profileLock.js +10 -0
- package/dist/browser/profileStore.d.ts +23 -0
- package/dist/browser/profileStore.js +39 -0
- package/dist/browser/runLiveness.d.ts +13 -0
- package/dist/browser/runLiveness.js +39 -0
- package/dist/browser/sitePolicy.d.ts +10 -0
- package/dist/browser/sitePolicy.js +61 -0
- package/dist/browser/stageBrowserEnv.d.ts +22 -0
- package/dist/browser/stageBrowserEnv.js +147 -0
- package/dist/browser/stageProfileLock.d.ts +17 -0
- package/dist/browser/stageProfileLock.js +39 -0
- package/dist/cli/browserCommand.d.ts +44 -0
- package/dist/cli/browserCommand.js +472 -0
- package/dist/cli/doctorCommand.js +7 -0
- package/dist/cli/hostClient.d.ts +20 -0
- package/dist/cli/hostClient.js +36 -2
- package/dist/cli/initCommand.d.ts +1 -0
- package/dist/cli/initCommand.js +23 -7
- package/dist/cli/initTemplates.d.ts +5 -2
- package/dist/cli/initTemplates.js +25 -2
- package/dist/cli/providersCommand.d.ts +1 -1
- package/dist/cli/providersCommand.js +4 -4
- package/dist/cli/runsCommand.js +6 -2
- package/dist/cli/triggerCommand.d.ts +12 -0
- package/dist/cli/triggerCommand.js +183 -0
- package/dist/cli/validateCommand.d.ts +1 -1
- package/dist/cli/validateCommand.js +23 -6
- package/dist/cli.js +32 -3
- package/dist/config/browseCatalog.d.ts +1 -0
- package/dist/config/browseCatalog.js +5 -4
- package/dist/config/builtinSkills.d.ts +4 -0
- package/dist/config/builtinSkills.js +23 -0
- package/dist/config/catalogRelativePath.d.ts +1 -0
- package/dist/config/catalogRelativePath.js +10 -2
- package/dist/config/createTrigger.d.ts +27 -0
- package/dist/config/createTrigger.js +232 -0
- package/dist/config/draftPackage.d.ts +117 -0
- package/dist/config/draftPackage.js +550 -0
- package/dist/config/ensureCatalogScanRoot.d.ts +16 -0
- package/dist/config/ensureCatalogScanRoot.js +73 -0
- package/dist/config/hostConfig.d.ts +2 -0
- package/dist/config/hostConfig.js +27 -0
- package/dist/config/listSkills.d.ts +2 -2
- package/dist/config/listSkills.js +17 -3
- package/dist/config/loadOutcome.d.ts +6 -0
- package/dist/config/loadPipeline.js +16 -0
- package/dist/config/loadStage.js +7 -0
- package/dist/config/loadStageflowManifest.js +25 -0
- package/dist/config/loadTrigger.d.ts +9 -0
- package/dist/config/loadTrigger.js +120 -0
- package/dist/config/multiProjectCatalog.d.ts +2 -0
- package/dist/config/multiProjectCatalog.js +26 -18
- package/dist/config/normalizePipelineStageEntry.js +8 -1
- package/dist/config/parseCompletionContract.js +6 -0
- package/dist/config/pipelineStageKeys.js +1 -0
- package/dist/config/publishDraftPackage.d.ts +7 -0
- package/dist/config/publishDraftPackage.js +25 -0
- package/dist/config/resolveCatalogContext.js +1 -1
- package/dist/config/resolvePipelineDag.js +1 -1
- package/dist/config/scanCatalogPaths.d.ts +1 -1
- package/dist/config/scanCatalogPaths.js +6 -2
- package/dist/config/stageBrowser.d.ts +12 -0
- package/dist/config/stageBrowser.js +118 -0
- package/dist/config/triggerCatalog.d.ts +10 -0
- package/dist/config/triggerCatalog.js +37 -0
- package/dist/config/validateCatalog.d.ts +13 -3
- package/dist/config/validateCatalog.js +83 -2
- package/dist/config/validateCompletionContract.js +8 -0
- package/dist/envelope/preEmitChecks.d.ts +1 -1
- package/dist/envelope/preEmitChecks.js +8 -0
- package/dist/logging/redact.d.ts +4 -0
- package/dist/logging/redact.js +17 -0
- package/dist/mcp/catalogTools.js +43 -8
- package/dist/mcp/controlTools.js +3 -1
- package/dist/mcp/deps.d.ts +2 -0
- package/dist/mcp/server.js +1 -0
- package/dist/mcp/tools.js +2 -0
- package/dist/mcp/triggerTools.d.ts +3 -0
- package/dist/mcp/triggerTools.js +176 -0
- package/dist/operatorAgent/docsRetrieval.d.ts +40 -0
- package/dist/operatorAgent/docsRetrieval.js +269 -0
- package/dist/operatorAgent/draftContext.d.ts +16 -0
- package/dist/operatorAgent/draftContext.js +68 -0
- package/dist/operatorAgent/fakeHost.d.ts +39 -0
- package/dist/operatorAgent/fakeHost.js +92 -0
- package/dist/operatorAgent/host.d.ts +40 -0
- package/dist/operatorAgent/host.js +179 -0
- package/dist/operatorAgent/index.d.ts +9 -0
- package/dist/operatorAgent/index.js +8 -0
- package/dist/operatorAgent/piModel.d.ts +80 -0
- package/dist/operatorAgent/piModel.js +528 -0
- package/dist/operatorAgent/profiles/workshopAuthor.d.ts +23 -0
- package/dist/operatorAgent/profiles/workshopAuthor.js +338 -0
- package/dist/operatorAgent/profiles/workshopAuthorPlaybook.d.ts +6 -0
- package/dist/operatorAgent/profiles/workshopAuthorPlaybook.js +103 -0
- package/dist/operatorAgent/profiles/workshopAuthorTools.d.ts +57 -0
- package/dist/operatorAgent/profiles/workshopAuthorTools.js +623 -0
- package/dist/operatorAgent/proposals.d.ts +32 -0
- package/dist/operatorAgent/proposals.js +144 -0
- package/dist/operatorAgent/types.d.ts +128 -0
- package/dist/operatorAgent/types.js +1 -0
- package/dist/package-meta.d.ts +1 -1
- package/dist/package-meta.js +1 -1
- package/dist/project/findManifestRoot.d.ts +3 -0
- package/dist/project/findManifestRoot.js +35 -0
- package/dist/project/resolveStageflowContext.d.ts +7 -0
- package/dist/project/resolveStageflowContext.js +44 -28
- package/dist/runstore/assertTmpdir.js +6 -2
- package/dist/runstore/diskUsage.d.ts +1 -1
- package/dist/runstore/diskUsage.js +2 -7
- package/dist/runstore/port.d.ts +28 -0
- package/dist/runstore/sqlite/SqliteRunStore.d.ts +8 -1
- package/dist/runstore/sqlite/SqliteRunStore.js +90 -0
- package/dist/runstore/sqlite/migrations/008-triggers-table.d.ts +7 -0
- package/dist/runstore/sqlite/migrations/008-triggers-table.js +19 -0
- package/dist/runstore/sqlite/migrations/009-trigger-next-run.d.ts +7 -0
- package/dist/runstore/sqlite/migrations/009-trigger-next-run.js +19 -0
- package/dist/runstore/sqlite/migrations/010-trigger-adapter-state.d.ts +7 -0
- package/dist/runstore/sqlite/migrations/010-trigger-adapter-state.js +17 -0
- package/dist/runstore/sqlite/migrations/index.js +6 -0
- package/dist/runtime/answerResume.d.ts +1 -0
- package/dist/runtime/answerResume.js +3 -1
- package/dist/runtime/completionCheckRunner.d.ts +12 -1
- package/dist/runtime/completionCheckRunner.js +22 -0
- package/dist/runtime/credentialBinding.d.ts +7 -2
- package/dist/runtime/credentialBinding.js +20 -28
- package/dist/runtime/emailSource.d.ts +72 -0
- package/dist/runtime/emailSource.js +304 -0
- package/dist/runtime/githubPollSource.d.ts +86 -0
- package/dist/runtime/githubPollSource.js +284 -0
- package/dist/runtime/pipelineRunner.d.ts +4 -0
- package/dist/runtime/pipelineRunner.js +3 -0
- package/dist/runtime/pipelineScheduler.d.ts +2 -0
- package/dist/runtime/pipelineScheduler.js +86 -1
- package/dist/runtime/repositoryMaterialize.d.ts +1 -1
- package/dist/runtime/runManager.d.ts +11 -0
- package/dist/runtime/runManager.js +161 -3
- package/dist/runtime/runRetryCoordinator.d.ts +2 -0
- package/dist/runtime/runRetryCoordinator.js +1 -0
- package/dist/runtime/scheduleSource.d.ts +38 -0
- package/dist/runtime/scheduleSource.js +119 -0
- package/dist/runtime/settingsFile.d.ts +7 -2
- package/dist/runtime/settingsFile.js +66 -56
- package/dist/runtime/stageAttemptBootstrap.js +55 -3
- package/dist/runtime/stageEnvironment.js +1 -0
- package/dist/runtime/stageHitl.d.ts +1 -0
- package/dist/runtime/stageHitl.js +5 -1
- package/dist/runtime/stageProcessLauncher.d.ts +3 -0
- package/dist/runtime/stageProcessLauncher.js +52 -5
- package/dist/runtime/stageRunner.d.ts +5 -0
- package/dist/runtime/stageRunner.js +30 -6
- package/dist/runtime/stageStreamLog.d.ts +1 -0
- package/dist/runtime/stageStreamLog.js +2 -1
- package/dist/runtime/triggerCatalog.d.ts +6 -0
- package/dist/runtime/triggerCatalog.js +24 -0
- package/dist/runtime/triggerEventMatch.d.ts +2 -0
- package/dist/runtime/triggerEventMatch.js +6 -0
- package/dist/runtime/triggerPort.d.ts +14 -0
- package/dist/runtime/triggerPort.js +1 -0
- package/dist/runtime/triggerRunner.d.ts +17 -0
- package/dist/runtime/triggerRunner.js +89 -0
- package/dist/runtime/verifiedStageExecution.d.ts +7 -0
- package/dist/runtime/verifiedStageExecution.js +14 -0
- package/dist/runtime/webhookSignature.d.ts +1 -0
- package/dist/runtime/webhookSignature.js +12 -0
- package/dist/server/bootstrap.d.ts +6 -0
- package/dist/server/bootstrap.js +70 -0
- package/dist/server/controlToken.js +13 -0
- package/dist/server/createHttpHost.js +3 -0
- package/dist/server/healthSurfaces.js +31 -6
- package/dist/server/http.d.ts +15 -0
- package/dist/server/http.js +1251 -74
- package/dist/server/requestAuthContext.d.ts +1 -1
- package/dist/server/triggerRoutes.d.ts +15 -0
- package/dist/server/triggerRoutes.js +268 -0
- package/dist/tools/askOperator.d.ts +3 -2
- package/dist/types/completion.d.ts +3 -0
- package/dist/types/pipeline.d.ts +3 -1
- package/dist/types/preEmitCheck.d.ts +7 -0
- package/dist/types/stage.d.ts +14 -0
- package/dist/types/stageflowManifest.d.ts +3 -0
- package/dist/types/trigger.d.ts +18 -0
- package/dist/types/trigger.js +1 -0
- package/dist/ui/assets/{index-CSsDued1.css → index-Bv4p1aPK.css} +1 -1
- package/dist/ui/assets/index-p8Iou3zk.js +133 -0
- package/dist/ui/index.html +2 -2
- package/dist/workshop/autosave.d.ts +58 -0
- package/dist/workshop/autosave.js +222 -0
- package/dist/workshop/buildStore.d.ts +79 -0
- package/dist/workshop/buildStore.js +326 -0
- package/dist/workshop/chatTurn.d.ts +232 -0
- package/dist/workshop/chatTurn.js +475 -0
- package/dist/workshop/modelSettings.d.ts +18 -0
- package/dist/workshop/modelSettings.js +44 -0
- package/dist/workshop/sessionStore.d.ts +61 -0
- package/dist/workshop/sessionStore.js +254 -0
- package/dist/workshop/workshopPin.d.ts +72 -0
- package/dist/workshop/workshopPin.js +193 -0
- package/examples/README.md +2 -1
- package/examples/browser-session/README.md +77 -0
- package/examples/browser-session/browser-session.pipeline.yaml +50 -0
- package/examples/browser-session/browser-session.task.yaml +6 -0
- package/examples/browser-session/check-login.yaml +22 -0
- package/examples/browser-session/fixture-server.mjs +64 -0
- package/examples/browser-session/human-login.yaml +31 -0
- package/examples/browser-session/merge.yaml +36 -0
- package/examples/browser-session/work-a.yaml +41 -0
- package/examples/browser-session/work-b.yaml +41 -0
- package/examples/conditional-fork/decide.yaml +1 -1
- package/examples/github-release/README.md +17 -3
- package/examples/stage-mcp/README.md +3 -2
- package/examples/stageflow.yaml +51 -0
- package/package.json +9 -4
- package/skills/stageflow/references/control-surface.md +3 -1
- package/skills/stageflow-author/references/stage-prompt-template.md +4 -4
- package/skills/stageflow-run/SKILL.md +2 -0
- package/skills/stageflow-run/references/task-and-pipeline-selection.md +3 -1
- package/skills/stageflow-setup/SKILL.md +11 -0
- package/dist/ui/assets/index-B6hlSXXn.js +0 -120
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { CatalogPathError, catalogPathErrorBody, resolveWritableCatalogRoot, } from "../config/catalogRelativePath.js";
|
|
3
|
+
import { createTrigger, parseCreateTriggerBody } from "../config/createTrigger.js";
|
|
4
|
+
import { loadCatalogTriggers } from "../config/triggerCatalog.js";
|
|
5
|
+
import { writeAudit } from "../logging/audit.js";
|
|
6
|
+
import { logger as rootLogger } from "../logging/logger.js";
|
|
7
|
+
import { resolveStageflowContext } from "../project/resolveStageflowContext.js";
|
|
8
|
+
import { fireTrigger } from "../runtime/triggerRunner.js";
|
|
9
|
+
import { mapStartFailure } from "../server/operatorResults.js";
|
|
10
|
+
import { callerIdFromRequestAuth, getRequestAuth, } from "../server/requestAuthContext.js";
|
|
11
|
+
import { textResult } from "./toolResults.js";
|
|
12
|
+
const auditLog = rootLogger.child({ component: "audit" });
|
|
13
|
+
const triggerScheduleSchema = z.object({
|
|
14
|
+
cron: z.string(),
|
|
15
|
+
timezone: z.string().optional(),
|
|
16
|
+
});
|
|
17
|
+
const gitIdentitySchema = z.object({
|
|
18
|
+
name: z.string().optional(),
|
|
19
|
+
email: z.string().optional(),
|
|
20
|
+
});
|
|
21
|
+
/**
|
|
22
|
+
* Same shape as TaskFile (src/types/task.ts), duplicated locally the same way
|
|
23
|
+
* src/mcp/catalogTools.ts's own taskFileSchema is: deliberately not shared
|
|
24
|
+
* across module boundaries for a schema this small.
|
|
25
|
+
*/
|
|
26
|
+
const taskFileSchema = z.object({
|
|
27
|
+
id: z.string(),
|
|
28
|
+
goal: z.string(),
|
|
29
|
+
context: z.string().optional(),
|
|
30
|
+
constraints: z.string().optional(),
|
|
31
|
+
checkout: z.string().optional(),
|
|
32
|
+
repository: z.string().optional(),
|
|
33
|
+
ref: z.string().optional(),
|
|
34
|
+
run_branch_template: z.string().optional(),
|
|
35
|
+
git_identity: gitIdentitySchema.optional(),
|
|
36
|
+
input: z.record(z.string(), z.unknown()).optional(),
|
|
37
|
+
});
|
|
38
|
+
const triggerEventSchema = z.object({
|
|
39
|
+
source: z.string(),
|
|
40
|
+
match: z.record(z.string(), z.unknown()).optional(),
|
|
41
|
+
config: z.record(z.string(), z.unknown()).optional(),
|
|
42
|
+
});
|
|
43
|
+
const createTriggerSchema = z.object({
|
|
44
|
+
project_root: z
|
|
45
|
+
.string()
|
|
46
|
+
.optional()
|
|
47
|
+
.describe("Catalog project root to write into; required when multiple catalog roots are configured and no sole non-seeded root exists"),
|
|
48
|
+
directory: z.string(),
|
|
49
|
+
id: z.string(),
|
|
50
|
+
pipeline: z.string(),
|
|
51
|
+
task: z
|
|
52
|
+
.string()
|
|
53
|
+
.optional()
|
|
54
|
+
.describe("Catalog task id; omit to create a dynamic-mode trigger whose task is supplied at fire time"),
|
|
55
|
+
kind: z.enum(["manual", "schedule", "event"]),
|
|
56
|
+
schedule: triggerScheduleSchema.optional(),
|
|
57
|
+
event: triggerEventSchema.optional(),
|
|
58
|
+
enabled: z.boolean().optional(),
|
|
59
|
+
});
|
|
60
|
+
export function registerTriggerTools(server, deps) {
|
|
61
|
+
const { store, cwd, manager } = deps;
|
|
62
|
+
server.registerTool("list_triggers", {
|
|
63
|
+
description: "List catalog-declared triggers (same source as GET /api/triggers): manual/schedule/event kind, enabled, and store-recorded last_fired_at/last_run_id/next_run_at when present.",
|
|
64
|
+
inputSchema: z.object({}),
|
|
65
|
+
}, async () => {
|
|
66
|
+
const items = await loadCatalogTriggers(cwd, store);
|
|
67
|
+
if (items === undefined) {
|
|
68
|
+
return textResult({ error: "No Stageflow catalog found", status: 404 }, true);
|
|
69
|
+
}
|
|
70
|
+
return textResult({ triggers: items });
|
|
71
|
+
});
|
|
72
|
+
server.registerTool("get_trigger", {
|
|
73
|
+
description: "Look up one catalog trigger by id (same source as GET /api/triggers/:id).",
|
|
74
|
+
inputSchema: z.object({
|
|
75
|
+
id: z.string(),
|
|
76
|
+
}),
|
|
77
|
+
}, async ({ id }) => {
|
|
78
|
+
const items = await loadCatalogTriggers(cwd, store);
|
|
79
|
+
if (items === undefined) {
|
|
80
|
+
return textResult({ error: "No Stageflow catalog found", status: 404 }, true);
|
|
81
|
+
}
|
|
82
|
+
const found = items.find((item) => item.id === id);
|
|
83
|
+
if (!found) {
|
|
84
|
+
return textResult({ error: `Trigger not found: ${id}`, status: 404 }, true);
|
|
85
|
+
}
|
|
86
|
+
return textResult(found);
|
|
87
|
+
});
|
|
88
|
+
server.registerTool("fire_trigger", {
|
|
89
|
+
description: "Fire a catalog trigger by id: resolves its pipeline/task refs and starts a run through the same RunManager.startRun path as start_run (same as POST /api/triggers/:id/fire). Returns { runId } or { runId, queued: true, queuePosition }. Fails not_found (404) for an unknown id, or 409 when the trigger is disabled.",
|
|
90
|
+
inputSchema: z.object({
|
|
91
|
+
id: z.string(),
|
|
92
|
+
task: taskFileSchema
|
|
93
|
+
.optional()
|
|
94
|
+
.describe("Inline TaskFile, required to fire a dynamic-mode trigger (no catalog task) and rejected for a catalog-mode trigger"),
|
|
95
|
+
}),
|
|
96
|
+
}, async ({ id, task }) => {
|
|
97
|
+
const callerId = callerIdFromRequestAuth();
|
|
98
|
+
const result = await fireTrigger(id, store, manager, { cwd, task });
|
|
99
|
+
if (!result.ok) {
|
|
100
|
+
writeAudit(auditLog, {
|
|
101
|
+
caller_id: callerId,
|
|
102
|
+
surface: getRequestAuth()?.surface ?? "mcp",
|
|
103
|
+
action: "trigger_fire",
|
|
104
|
+
outcome: "error",
|
|
105
|
+
error_code: result.code,
|
|
106
|
+
});
|
|
107
|
+
return textResult({
|
|
108
|
+
...mapStartFailure(result),
|
|
109
|
+
...(result.status !== undefined ? { status: result.status } : {}),
|
|
110
|
+
}, true);
|
|
111
|
+
}
|
|
112
|
+
writeAudit(auditLog, {
|
|
113
|
+
caller_id: callerId,
|
|
114
|
+
surface: getRequestAuth()?.surface ?? "mcp",
|
|
115
|
+
action: "trigger_fire",
|
|
116
|
+
target_run_id: result.runId,
|
|
117
|
+
outcome: "ok",
|
|
118
|
+
});
|
|
119
|
+
return textResult({
|
|
120
|
+
runId: result.runId,
|
|
121
|
+
...(result.queued === true
|
|
122
|
+
? {
|
|
123
|
+
queued: true,
|
|
124
|
+
queuePosition: result.queuePosition,
|
|
125
|
+
...(result.queuedCode !== undefined
|
|
126
|
+
? { queuedCode: result.queuedCode }
|
|
127
|
+
: {}),
|
|
128
|
+
}
|
|
129
|
+
: {}),
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
server.registerTool("create_trigger", {
|
|
133
|
+
description: "Create a new *.trigger.yaml in the catalog (same validation/write path as POST /api/triggers): validates id format/uniqueness, pipeline/task refs, and kind-specific shape (schedule.cron parses via croner; event.source is required), writes the file, and re-loads it to confirm it round-trips. Returns the created trigger.",
|
|
134
|
+
inputSchema: createTriggerSchema,
|
|
135
|
+
}, async ({ project_root, ...body }) => {
|
|
136
|
+
const callerId = callerIdFromRequestAuth();
|
|
137
|
+
let wireRoot;
|
|
138
|
+
try {
|
|
139
|
+
({ wireRoot } = await resolveWritableCatalogRoot({ store, bootCwd: cwd }, project_root));
|
|
140
|
+
}
|
|
141
|
+
catch (err) {
|
|
142
|
+
if (err instanceof CatalogPathError) {
|
|
143
|
+
return textResult(catalogPathErrorBody(err), true);
|
|
144
|
+
}
|
|
145
|
+
throw err;
|
|
146
|
+
}
|
|
147
|
+
const parsed = parseCreateTriggerBody(body);
|
|
148
|
+
if ("ok" in parsed) {
|
|
149
|
+
return textResult({ error: parsed.error, status: parsed.status }, true);
|
|
150
|
+
}
|
|
151
|
+
const stageflowCtx = await resolveStageflowContext(wireRoot.path);
|
|
152
|
+
if (stageflowCtx.manifestStatus !== "ok") {
|
|
153
|
+
return textResult({
|
|
154
|
+
error: "Project root not found; initialize stageflow.yaml",
|
|
155
|
+
status: 400,
|
|
156
|
+
}, true);
|
|
157
|
+
}
|
|
158
|
+
const result = await createTrigger(stageflowCtx.projectRoot, parsed);
|
|
159
|
+
if (!result.ok) {
|
|
160
|
+
writeAudit(auditLog, {
|
|
161
|
+
caller_id: callerId,
|
|
162
|
+
surface: getRequestAuth()?.surface ?? "mcp",
|
|
163
|
+
action: "trigger_create",
|
|
164
|
+
outcome: "error",
|
|
165
|
+
});
|
|
166
|
+
return textResult({ error: result.error, status: result.status }, true);
|
|
167
|
+
}
|
|
168
|
+
writeAudit(auditLog, {
|
|
169
|
+
caller_id: callerId,
|
|
170
|
+
surface: getRequestAuth()?.surface ?? "mcp",
|
|
171
|
+
action: "trigger_create",
|
|
172
|
+
outcome: "ok",
|
|
173
|
+
});
|
|
174
|
+
return textResult(result.trigger);
|
|
175
|
+
});
|
|
176
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export type DocsRetrievalHit = {
|
|
2
|
+
path: string;
|
|
3
|
+
kind: "doc" | "example";
|
|
4
|
+
title: string;
|
|
5
|
+
excerpt: string;
|
|
6
|
+
};
|
|
7
|
+
export type DocsRetrievalResult = {
|
|
8
|
+
ok: boolean;
|
|
9
|
+
hits: DocsRetrievalHit[];
|
|
10
|
+
error?: string;
|
|
11
|
+
};
|
|
12
|
+
export type DocsRetriever = {
|
|
13
|
+
retrieve(query: string, options?: {
|
|
14
|
+
kind?: "docs" | "examples" | "any";
|
|
15
|
+
limit?: number;
|
|
16
|
+
}): Promise<DocsRetrievalResult>;
|
|
17
|
+
};
|
|
18
|
+
type CorpusEntry = {
|
|
19
|
+
path: string;
|
|
20
|
+
kind: "doc" | "example";
|
|
21
|
+
title: string;
|
|
22
|
+
topics: string[];
|
|
23
|
+
};
|
|
24
|
+
declare const CORPUS: CorpusEntry[];
|
|
25
|
+
export declare function resolveWorkshopCatalogRoot(explicit?: string): string;
|
|
26
|
+
/**
|
|
27
|
+
* Filesystem retriever over public docs/ + examples/ (allowlisted).
|
|
28
|
+
* Read failures for individual paths are skipped; empty matches still ok:true.
|
|
29
|
+
* Thrown/unexpected errors surface as ok:false so the agent can fall back to
|
|
30
|
+
* the baked playbook.
|
|
31
|
+
*/
|
|
32
|
+
export declare function createFilesystemDocsRetriever(options?: {
|
|
33
|
+
rootDir?: string;
|
|
34
|
+
}): DocsRetriever;
|
|
35
|
+
export declare function createStubDocsRetriever(impl: DocsRetrievalHit[] | ((query: string, options?: {
|
|
36
|
+
kind?: "docs" | "examples" | "any";
|
|
37
|
+
limit?: number;
|
|
38
|
+
}) => DocsRetrievalResult | Promise<DocsRetrievalResult>)): DocsRetriever;
|
|
39
|
+
export declare function createFailingDocsRetriever(error?: string): DocsRetriever;
|
|
40
|
+
export { CORPUS as WORKSHOP_DOCS_CORPUS };
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
const CORPUS = [
|
|
5
|
+
{
|
|
6
|
+
path: "docs/yaml-catalog.md",
|
|
7
|
+
kind: "doc",
|
|
8
|
+
title: "YAML catalog",
|
|
9
|
+
topics: [
|
|
10
|
+
"yaml",
|
|
11
|
+
"catalog",
|
|
12
|
+
"io",
|
|
13
|
+
"verify",
|
|
14
|
+
"on_verify_fail",
|
|
15
|
+
"route",
|
|
16
|
+
"entry",
|
|
17
|
+
"clone",
|
|
18
|
+
"clone-chain",
|
|
19
|
+
"feedback",
|
|
20
|
+
"loop",
|
|
21
|
+
"mcp",
|
|
22
|
+
"dag",
|
|
23
|
+
"linear",
|
|
24
|
+
],
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
path: "docs/envelopes.md",
|
|
28
|
+
kind: "doc",
|
|
29
|
+
title: "Envelopes",
|
|
30
|
+
topics: ["envelope", "artifacts", "emit", "payload", "summary", "status"],
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
path: "docs/hitl.md",
|
|
34
|
+
kind: "doc",
|
|
35
|
+
title: "HITL",
|
|
36
|
+
topics: [
|
|
37
|
+
"hitl",
|
|
38
|
+
"ask_operator",
|
|
39
|
+
"gate",
|
|
40
|
+
"gate_kinds",
|
|
41
|
+
"confirm",
|
|
42
|
+
"free_text",
|
|
43
|
+
"artifact_backed",
|
|
44
|
+
],
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
path: "docs/verified-stage-execution.md",
|
|
48
|
+
kind: "doc",
|
|
49
|
+
title: "Verified stage execution",
|
|
50
|
+
topics: [
|
|
51
|
+
"verify",
|
|
52
|
+
"vse",
|
|
53
|
+
"recovery",
|
|
54
|
+
"repair",
|
|
55
|
+
"manual",
|
|
56
|
+
"on_verify_fail",
|
|
57
|
+
"after",
|
|
58
|
+
],
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
path: "docs/mcp.md",
|
|
62
|
+
kind: "doc",
|
|
63
|
+
title: "MCP",
|
|
64
|
+
topics: ["mcp", "tools", "stageflow", "server"],
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
path: "examples/README.md",
|
|
68
|
+
kind: "example",
|
|
69
|
+
title: "Examples index",
|
|
70
|
+
topics: ["examples", "walkthrough", "catalog"],
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
path: "examples/hello-world/README.md",
|
|
74
|
+
kind: "example",
|
|
75
|
+
title: "hello-world",
|
|
76
|
+
topics: ["hello", "linear", "task.input", "io"],
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
path: "examples/plan-review/README.md",
|
|
80
|
+
kind: "example",
|
|
81
|
+
title: "plan-review",
|
|
82
|
+
topics: ["plan", "review", "hitl", "gate", "multi-stage"],
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
path: "examples/conditional-fork/README.md",
|
|
86
|
+
kind: "example",
|
|
87
|
+
title: "conditional-fork",
|
|
88
|
+
topics: ["fork", "route", "if", "branch", "hitl"],
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
path: "examples/feedback-loop/README.md",
|
|
92
|
+
kind: "example",
|
|
93
|
+
title: "feedback-loop",
|
|
94
|
+
topics: ["feedback", "loop", "send_back", "continue", "replay"],
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
path: "examples/feature-loop/README.md",
|
|
98
|
+
kind: "example",
|
|
99
|
+
title: "feature-loop",
|
|
100
|
+
topics: ["clone", "clone-chain", "loop", "feature", "pr"],
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
path: "examples/stage-mcp/README.md",
|
|
104
|
+
kind: "example",
|
|
105
|
+
title: "stage-mcp",
|
|
106
|
+
topics: ["mcp", "stage", ".mcp.json"],
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
path: "examples/verify-tour/README.md",
|
|
110
|
+
kind: "example",
|
|
111
|
+
title: "verify-tour",
|
|
112
|
+
topics: ["verify", "artifact", "command", "checklist", "gate"],
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
path: "examples/retry-tour/README.md",
|
|
116
|
+
kind: "example",
|
|
117
|
+
title: "retry-tour",
|
|
118
|
+
topics: ["retry", "repair", "manual", "recover", "recovery"],
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
path: "skills/stageflow-author/assets/examples/linear-review/review-loop.pipeline.yaml",
|
|
122
|
+
kind: "example",
|
|
123
|
+
title: "linear-review (author skill)",
|
|
124
|
+
topics: ["linear", "review", "author", "skill"],
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
path: "skills/stageflow-author/assets/examples/branch-decision/release-gate.pipeline.yaml",
|
|
128
|
+
kind: "example",
|
|
129
|
+
title: "branch-decision (author skill)",
|
|
130
|
+
topics: ["branch", "decision", "route", "if", "author"],
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
path: "skills/stageflow-author/assets/examples/non-sdlc-digest/research-digest.pipeline.yaml",
|
|
134
|
+
kind: "example",
|
|
135
|
+
title: "non-sdlc-digest (author skill)",
|
|
136
|
+
topics: ["digest", "non-sdlc", "research", "author"],
|
|
137
|
+
},
|
|
138
|
+
];
|
|
139
|
+
const EXCERPT_MAX = 1200;
|
|
140
|
+
export function resolveWorkshopCatalogRoot(explicit) {
|
|
141
|
+
if (explicit)
|
|
142
|
+
return explicit;
|
|
143
|
+
return fileURLToPath(new URL("../..", import.meta.url));
|
|
144
|
+
}
|
|
145
|
+
function tokenize(query) {
|
|
146
|
+
return query
|
|
147
|
+
.toLowerCase()
|
|
148
|
+
.split(/[^a-z0-9_./-]+/)
|
|
149
|
+
.map((t) => t.trim())
|
|
150
|
+
.filter((t) => t.length >= 2);
|
|
151
|
+
}
|
|
152
|
+
function scoreEntry(entry, tokens) {
|
|
153
|
+
if (tokens.length === 0)
|
|
154
|
+
return 1;
|
|
155
|
+
let score = 0;
|
|
156
|
+
const hay = `${entry.path} ${entry.title} ${entry.topics.join(" ")}`.toLowerCase();
|
|
157
|
+
for (const token of tokens) {
|
|
158
|
+
if (entry.topics.includes(token))
|
|
159
|
+
score += 4;
|
|
160
|
+
else if (hay.includes(token))
|
|
161
|
+
score += 2;
|
|
162
|
+
}
|
|
163
|
+
return score;
|
|
164
|
+
}
|
|
165
|
+
async function readExcerpt(absPath) {
|
|
166
|
+
try {
|
|
167
|
+
const text = await readFile(absPath, "utf8");
|
|
168
|
+
const trimmed = text.trim();
|
|
169
|
+
if (!trimmed)
|
|
170
|
+
return null;
|
|
171
|
+
return trimmed.length > EXCERPT_MAX
|
|
172
|
+
? `${trimmed.slice(0, EXCERPT_MAX)}…`
|
|
173
|
+
: trimmed;
|
|
174
|
+
}
|
|
175
|
+
catch {
|
|
176
|
+
return null;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Filesystem retriever over public docs/ + examples/ (allowlisted).
|
|
181
|
+
* Read failures for individual paths are skipped; empty matches still ok:true.
|
|
182
|
+
* Thrown/unexpected errors surface as ok:false so the agent can fall back to
|
|
183
|
+
* the baked playbook.
|
|
184
|
+
*/
|
|
185
|
+
export function createFilesystemDocsRetriever(options = {}) {
|
|
186
|
+
const rootDir = resolveWorkshopCatalogRoot(options.rootDir);
|
|
187
|
+
return {
|
|
188
|
+
async retrieve(query, opts = {}) {
|
|
189
|
+
try {
|
|
190
|
+
const kind = opts.kind ?? "any";
|
|
191
|
+
const limit = Math.max(1, Math.min(opts.limit ?? 5, 10));
|
|
192
|
+
const tokens = tokenize(query);
|
|
193
|
+
const ranked = CORPUS.map((entry) => ({
|
|
194
|
+
entry,
|
|
195
|
+
score: scoreEntry(entry, tokens),
|
|
196
|
+
}))
|
|
197
|
+
.filter(({ entry, score }) => {
|
|
198
|
+
if (score <= 0)
|
|
199
|
+
return false;
|
|
200
|
+
if (kind === "docs")
|
|
201
|
+
return entry.kind === "doc";
|
|
202
|
+
if (kind === "examples")
|
|
203
|
+
return entry.kind === "example";
|
|
204
|
+
return true;
|
|
205
|
+
})
|
|
206
|
+
.sort((a, b) => b.score - a.score || a.entry.path.localeCompare(b.entry.path));
|
|
207
|
+
const hits = [];
|
|
208
|
+
for (const { entry } of ranked) {
|
|
209
|
+
if (hits.length >= limit)
|
|
210
|
+
break;
|
|
211
|
+
const abs = path.join(rootDir, entry.path);
|
|
212
|
+
let excerpt = await readExcerpt(abs);
|
|
213
|
+
if (excerpt === null && entry.path.endsWith("/README.md")) {
|
|
214
|
+
const dir = path.dirname(entry.path);
|
|
215
|
+
const fallback = path.join(rootDir, dir, "README.md");
|
|
216
|
+
excerpt = await readExcerpt(fallback);
|
|
217
|
+
}
|
|
218
|
+
if (excerpt === null)
|
|
219
|
+
continue;
|
|
220
|
+
hits.push({
|
|
221
|
+
path: entry.path,
|
|
222
|
+
kind: entry.kind,
|
|
223
|
+
title: entry.title,
|
|
224
|
+
excerpt,
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
return { ok: true, hits };
|
|
228
|
+
}
|
|
229
|
+
catch (err) {
|
|
230
|
+
return {
|
|
231
|
+
ok: false,
|
|
232
|
+
hits: [],
|
|
233
|
+
error: err instanceof Error ? err.message : String(err),
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
},
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
export function createStubDocsRetriever(impl) {
|
|
240
|
+
if (typeof impl === "function") {
|
|
241
|
+
return {
|
|
242
|
+
async retrieve(query, options) {
|
|
243
|
+
try {
|
|
244
|
+
return await impl(query, options);
|
|
245
|
+
}
|
|
246
|
+
catch (err) {
|
|
247
|
+
return {
|
|
248
|
+
ok: false,
|
|
249
|
+
hits: [],
|
|
250
|
+
error: err instanceof Error ? err.message : String(err),
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
},
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
return {
|
|
257
|
+
async retrieve() {
|
|
258
|
+
return { ok: true, hits: impl };
|
|
259
|
+
},
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
export function createFailingDocsRetriever(error = "docs retrieval unavailable") {
|
|
263
|
+
return {
|
|
264
|
+
async retrieve() {
|
|
265
|
+
return { ok: false, hits: [], error };
|
|
266
|
+
},
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
export { CORPUS as WORKSHOP_DOCS_CORPUS };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { DraftPackage } from "../config/draftPackage.js";
|
|
2
|
+
import type { OperatorAgentContextAdapter, WorkshopDraftContext } from "./types.js";
|
|
3
|
+
export declare const WORKSHOP_AUTHOR_GREETING = "What are we building? Tell me the workflow in your own words \u2014 I\u2019ll ask where it changes the draft.";
|
|
4
|
+
export declare function emptyDraftPackage(id?: string): DraftPackage;
|
|
5
|
+
export type WorkshopDraftContextExtras = Omit<WorkshopDraftContext, "draft">;
|
|
6
|
+
export declare function createWorkshopDraftContext(draft?: DraftPackage, extras?: WorkshopDraftContextExtras): WorkshopDraftContext;
|
|
7
|
+
export declare function isWorkshopDraftContext(value: unknown): value is WorkshopDraftContext;
|
|
8
|
+
export declare function readDraftFromContext(context: unknown): DraftPackage;
|
|
9
|
+
export declare function withDraft(context: unknown, draft: DraftPackage): WorkshopDraftContext;
|
|
10
|
+
export declare function withDestination(context: unknown, destination: WorkshopDraftContext["destination"]): WorkshopDraftContext;
|
|
11
|
+
export declare function withProjectRoot(context: unknown, projectRoot: string): WorkshopDraftContext;
|
|
12
|
+
export declare const workshopDraftContextAdapter: OperatorAgentContextAdapter;
|
|
13
|
+
export declare function draftTrackStages(draft: DraftPackage): Array<{
|
|
14
|
+
id: string;
|
|
15
|
+
label: string;
|
|
16
|
+
}>;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
export const WORKSHOP_AUTHOR_GREETING = "What are we building? Tell me the workflow in your own words — I’ll ask where it changes the draft.";
|
|
2
|
+
export function emptyDraftPackage(id = "untitled") {
|
|
3
|
+
return {
|
|
4
|
+
pipeline: {
|
|
5
|
+
id,
|
|
6
|
+
stages: [],
|
|
7
|
+
},
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
export function createWorkshopDraftContext(draft = emptyDraftPackage(), extras = {}) {
|
|
11
|
+
return { draft, ...extras };
|
|
12
|
+
}
|
|
13
|
+
export function isWorkshopDraftContext(value) {
|
|
14
|
+
return (value !== null &&
|
|
15
|
+
typeof value === "object" &&
|
|
16
|
+
"draft" in value &&
|
|
17
|
+
value.draft !== null &&
|
|
18
|
+
typeof value.draft === "object");
|
|
19
|
+
}
|
|
20
|
+
export function readDraftFromContext(context) {
|
|
21
|
+
if (isWorkshopDraftContext(context))
|
|
22
|
+
return context.draft;
|
|
23
|
+
if (context !== null &&
|
|
24
|
+
typeof context === "object" &&
|
|
25
|
+
"pipeline" in context) {
|
|
26
|
+
return context;
|
|
27
|
+
}
|
|
28
|
+
return emptyDraftPackage();
|
|
29
|
+
}
|
|
30
|
+
export function withDraft(context, draft) {
|
|
31
|
+
if (isWorkshopDraftContext(context)) {
|
|
32
|
+
return { ...context, draft };
|
|
33
|
+
}
|
|
34
|
+
return { draft };
|
|
35
|
+
}
|
|
36
|
+
export function withDestination(context, destination) {
|
|
37
|
+
const base = isWorkshopDraftContext(context)
|
|
38
|
+
? context
|
|
39
|
+
: { draft: readDraftFromContext(context) };
|
|
40
|
+
return { ...base, destination };
|
|
41
|
+
}
|
|
42
|
+
export function withProjectRoot(context, projectRoot) {
|
|
43
|
+
const base = isWorkshopDraftContext(context)
|
|
44
|
+
? context
|
|
45
|
+
: { draft: readDraftFromContext(context) };
|
|
46
|
+
return { ...base, projectRoot };
|
|
47
|
+
}
|
|
48
|
+
export const workshopDraftContextAdapter = {
|
|
49
|
+
serialize(context) {
|
|
50
|
+
return readDraftFromContext(context);
|
|
51
|
+
},
|
|
52
|
+
applyProposal(context, proposal) {
|
|
53
|
+
const next = proposal.nextContext;
|
|
54
|
+
if (isWorkshopDraftContext(next)) {
|
|
55
|
+
return withDraft(context, next.draft);
|
|
56
|
+
}
|
|
57
|
+
if (next !== null && typeof next === "object" && "pipeline" in next) {
|
|
58
|
+
return withDraft(context, next);
|
|
59
|
+
}
|
|
60
|
+
return withDraft(context, readDraftFromContext(context));
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
export function draftTrackStages(draft) {
|
|
64
|
+
return draft.pipeline.stages.map((stage, index) => {
|
|
65
|
+
const id = typeof stage.id === "string" && stage.id ? stage.id : `stage-${index}`;
|
|
66
|
+
return { id, label: id };
|
|
67
|
+
});
|
|
68
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { type OperatorAgentModel } from "./host.js";
|
|
2
|
+
import type { DocsRetriever } from "./docsRetrieval.js";
|
|
3
|
+
import { WORKSHOP_AUTHOR_PROFILE_ID, type WorkshopAuthorProfileOptions } from "./profiles/workshopAuthor.js";
|
|
4
|
+
import type { OperatorAgentHost, OperatorAgentProposal, OperatorAgentSessionEvent } from "./types.js";
|
|
5
|
+
export type FakeOperatorTurn = {
|
|
6
|
+
type: "echo";
|
|
7
|
+
} | {
|
|
8
|
+
type: "propose_stage";
|
|
9
|
+
} | {
|
|
10
|
+
type: "propose_task";
|
|
11
|
+
} | {
|
|
12
|
+
type: "events";
|
|
13
|
+
events: OperatorAgentSessionEvent[];
|
|
14
|
+
} | {
|
|
15
|
+
type: "propose";
|
|
16
|
+
proposal: OperatorAgentProposal;
|
|
17
|
+
message?: string;
|
|
18
|
+
} | {
|
|
19
|
+
type: "call_tool";
|
|
20
|
+
name: string;
|
|
21
|
+
args?: Record<string, unknown>;
|
|
22
|
+
message?: string;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Deterministic Operator Agent Host for Workshop and tests.
|
|
26
|
+
* Does not call a live provider — scripted turns or auto stage/task mutations.
|
|
27
|
+
*/
|
|
28
|
+
export declare function createFakeOperatorAgentModel(script?: FakeOperatorTurn[]): OperatorAgentModel;
|
|
29
|
+
export type WorkshopOperatorHostOptions = WorkshopAuthorProfileOptions & {
|
|
30
|
+
script?: FakeOperatorTurn[];
|
|
31
|
+
retriever?: DocsRetriever;
|
|
32
|
+
/**
|
|
33
|
+
* Inject a model (e.g. live Pi). When omitted, uses the fake scripted model
|
|
34
|
+
* — keep as the test / default path (R13).
|
|
35
|
+
*/
|
|
36
|
+
model?: OperatorAgentModel;
|
|
37
|
+
};
|
|
38
|
+
export declare function createWorkshopOperatorHost(scriptOrOptions?: FakeOperatorTurn[] | WorkshopOperatorHostOptions): OperatorAgentHost;
|
|
39
|
+
export { WORKSHOP_AUTHOR_PROFILE_ID };
|