@aglyn/plugins-ai 1.0.0-beta.228 → 1.0.0-beta.230
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 +3 -3
- package/package.json +17 -17
- package/src/lib/activity/ai-activity-actions.js +7 -1
- package/src/lib/activity/ai-activity-actions.js.map +1 -1
- package/src/lib/components/ai-automation-zones.d.ts +38 -0
- package/src/lib/components/ai-automation-zones.js +5 -1
- package/src/lib/components/ai-automation-zones.js.map +1 -1
- package/src/lib/components/ai-brief-dialog.component.d.ts +20 -2
- package/src/lib/components/ai-brief-dialog.component.js +87 -8
- package/src/lib/components/ai-brief-dialog.component.js.map +1 -1
- package/src/lib/components/ai-campaign-create.component.d.ts +54 -0
- package/src/lib/components/ai-campaign-create.component.js +270 -0
- package/src/lib/components/ai-campaign-create.component.js.map +1 -0
- package/src/lib/components/ai-describe-automation.component.d.ts +8 -3
- package/src/lib/components/ai-describe-automation.component.js +15 -6
- package/src/lib/components/ai-describe-automation.component.js.map +1 -1
- package/src/lib/components/ai-describe-button.component.d.ts +20 -8
- package/src/lib/components/ai-describe-button.component.js +19 -36
- package/src/lib/components/ai-describe-button.component.js.map +1 -1
- package/src/lib/components/ai-describe-email.component.d.ts +31 -0
- package/src/lib/components/ai-describe-email.component.js +22 -0
- package/src/lib/components/ai-describe-email.component.js.map +1 -0
- package/src/lib/components/ai-describe-org-automation.component.d.ts +36 -0
- package/src/lib/components/ai-describe-org-automation.component.js +238 -0
- package/src/lib/components/ai-describe-org-automation.component.js.map +1 -0
- package/src/lib/components/ai-experiment-cards.component.d.ts +9 -1
- package/src/lib/components/ai-experiment-cards.component.js +104 -18
- package/src/lib/components/ai-experiment-cards.component.js.map +1 -1
- package/src/lib/components/ai-explain-automation.component.js +1 -5
- package/src/lib/components/ai-explain-automation.component.js.map +1 -1
- package/src/lib/components/ai-funnel-zones.component.d.ts +61 -0
- package/src/lib/components/ai-funnel-zones.component.js +178 -0
- package/src/lib/components/ai-funnel-zones.component.js.map +1 -0
- package/src/lib/components/ai-insight-card.component.d.ts +42 -0
- package/src/lib/components/ai-insight-card.component.js +137 -0
- package/src/lib/components/ai-insight-card.component.js.map +1 -0
- package/src/lib/components/ai-insight-dialog.component.d.ts +6 -0
- package/src/lib/components/ai-insight-dialog.component.js +9 -3
- package/src/lib/components/ai-insight-dialog.component.js.map +1 -1
- package/src/lib/components/ai-job-plan.component.d.ts +7 -2
- package/src/lib/components/ai-job-plan.component.js +35 -5
- package/src/lib/components/ai-job-plan.component.js.map +1 -1
- package/src/lib/components/ai-job-requests.d.ts +17 -1
- package/src/lib/components/ai-job-requests.js +39 -3
- package/src/lib/components/ai-job-requests.js.map +1 -1
- package/src/lib/components/ai-jobs-list-page.component.js +12 -1
- package/src/lib/components/ai-jobs-list-page.component.js.map +1 -1
- package/src/lib/components/ai-logic-zones.d.ts +64 -0
- package/src/lib/components/ai-logic-zones.js +18 -0
- package/src/lib/components/ai-logic-zones.js.map +1 -0
- package/src/lib/components/ai-logic.component.d.ts +77 -0
- package/src/lib/components/ai-logic.component.js +553 -0
- package/src/lib/components/ai-logic.component.js.map +1 -0
- package/src/lib/components/ai-marketing-insight.component.d.ts +30 -0
- package/src/lib/components/ai-marketing-insight.component.js +80 -0
- package/src/lib/components/ai-marketing-insight.component.js.map +1 -0
- package/src/lib/components/ai-media-create.component.d.ts +55 -0
- package/src/lib/components/ai-media-create.component.js +433 -0
- package/src/lib/components/ai-media-create.component.js.map +1 -0
- package/src/lib/components/ai-overlay-cards.component.d.ts +83 -0
- package/src/lib/components/ai-overlay-cards.component.js +505 -0
- package/src/lib/components/ai-overlay-cards.component.js.map +1 -0
- package/src/lib/components/ai-product-zones.d.ts +5 -0
- package/src/lib/components/ai-product-zones.js +1 -1
- package/src/lib/components/ai-product-zones.js.map +1 -1
- package/src/lib/components/ai-products-create-button.component.d.ts +42 -0
- package/src/lib/components/ai-products-create-button.component.js +67 -0
- package/src/lib/components/ai-products-create-button.component.js.map +1 -0
- package/src/lib/components/ai-products-hub-card.component.js +100 -81
- package/src/lib/components/ai-products-hub-card.component.js.map +1 -1
- package/src/lib/components/ai-revise-automation.component.d.ts +16 -0
- package/src/lib/components/ai-revise-automation.component.js +207 -0
- package/src/lib/components/ai-revise-automation.component.js.map +1 -0
- package/src/lib/components/ai-site-build-page.component.d.ts +1 -1
- package/src/lib/components/ai-site-build-page.component.js +177 -20
- package/src/lib/components/ai-site-build-page.component.js.map +1 -1
- package/src/lib/components/ai-site-start-card.component.d.ts +10 -1
- package/src/lib/components/ai-site-start-card.component.js +7 -4
- package/src/lib/components/ai-site-start-card.component.js.map +1 -1
- package/src/lib/components/ai-upsell-dialog.component.d.ts +53 -0
- package/src/lib/components/ai-upsell-dialog.component.js +177 -0
- package/src/lib/components/ai-upsell-dialog.component.js.map +1 -0
- package/src/lib/components/assist-build-card.component.d.ts +42 -0
- package/src/lib/components/assist-build-card.component.js +183 -0
- package/src/lib/components/assist-build-card.component.js.map +1 -0
- package/src/lib/components/assist-edit-canvas.d.ts +2 -0
- package/src/lib/components/assist-edit-canvas.js +56 -1
- package/src/lib/components/assist-edit-canvas.js.map +1 -1
- package/src/lib/components/assist-jobs-drawer.component.d.ts +11 -0
- package/src/lib/components/assist-jobs-drawer.component.js +85 -4
- package/src/lib/components/assist-jobs-drawer.component.js.map +1 -1
- package/src/lib/components/assist-panel.component.js +51 -2
- package/src/lib/components/assist-panel.component.js.map +1 -1
- package/src/lib/components/use-ai-job-run.d.ts +3 -14
- package/src/lib/components/use-ai-job-run.js +0 -50
- package/src/lib/components/use-ai-job-run.js.map +1 -1
- package/src/lib/jobs/ai-build-capabilities.d.ts +58 -0
- package/src/lib/jobs/ai-build-capabilities.js +256 -0
- package/src/lib/jobs/ai-build-capabilities.js.map +1 -0
- package/src/lib/jobs/ai-build-unit-outcome.d.ts +52 -0
- package/src/lib/jobs/ai-build-unit-outcome.js +138 -0
- package/src/lib/jobs/ai-build-unit-outcome.js.map +1 -0
- package/src/lib/jobs/ai-job-build-step.d.ts +144 -0
- package/src/lib/jobs/ai-job-build-step.js +657 -0
- package/src/lib/jobs/ai-job-build-step.js.map +1 -0
- package/src/lib/jobs/ai-job-draft-ids.js +9 -1
- package/src/lib/jobs/ai-job-draft-ids.js.map +1 -1
- package/src/lib/jobs/ai-job-drafts.d.ts +14 -4
- package/src/lib/jobs/ai-job-drafts.js +25 -4
- package/src/lib/jobs/ai-job-drafts.js.map +1 -1
- package/src/lib/jobs/ai-job-layout-site-pages.d.ts +70 -0
- package/src/lib/jobs/ai-job-layout-site-pages.js +216 -0
- package/src/lib/jobs/ai-job-layout-site-pages.js.map +1 -0
- package/src/lib/jobs/ai-job-layout-step.d.ts +2 -2
- package/src/lib/jobs/ai-job-layout-step.js +19 -1
- package/src/lib/jobs/ai-job-layout-step.js.map +1 -1
- package/src/lib/jobs/ai-job-logic-step.d.ts +107 -0
- package/src/lib/jobs/ai-job-logic-step.js +395 -0
- package/src/lib/jobs/ai-job-logic-step.js.map +1 -0
- package/src/lib/jobs/ai-job-overlay-copy.d.ts +70 -0
- package/src/lib/jobs/ai-job-overlay-copy.js +178 -0
- package/src/lib/jobs/ai-job-overlay-copy.js.map +1 -0
- package/src/lib/jobs/ai-job-page-step.js +6 -6
- package/src/lib/jobs/ai-job-page-step.js.map +1 -1
- package/src/lib/jobs/ai-job-plan-step.d.ts +26 -1
- package/src/lib/jobs/ai-job-plan-step.js +79 -11
- package/src/lib/jobs/ai-job-plan-step.js.map +1 -1
- package/src/lib/jobs/ai-job-site-step.d.ts +15 -1
- package/src/lib/jobs/ai-job-site-step.js +207 -58
- package/src/lib/jobs/ai-job-site-step.js.map +1 -1
- package/src/lib/jobs/ai-job-text-step.d.ts +22 -1
- package/src/lib/jobs/ai-job-text-step.js +12 -0
- package/src/lib/jobs/ai-job-text-step.js.map +1 -1
- package/src/lib/jobs/ai-job-workflow-step.d.ts +54 -4
- package/src/lib/jobs/ai-job-workflow-step.js +318 -13
- package/src/lib/jobs/ai-job-workflow-step.js.map +1 -1
- package/src/lib/jobs/ai-jobs.d.ts +90 -2
- package/src/lib/jobs/ai-jobs.js +495 -61
- package/src/lib/jobs/ai-jobs.js.map +1 -1
- package/src/lib/jobs/ai-logic-records.d.ts +40 -0
- package/src/lib/jobs/ai-logic-records.js +55 -0
- package/src/lib/jobs/ai-logic-records.js.map +1 -0
- package/src/lib/jobs/ai-site-publish.d.ts +7 -0
- package/src/lib/jobs/ai-site-publish.js +9 -0
- package/src/lib/jobs/ai-site-publish.js.map +1 -1
- package/src/lib/jobs/ai-workflow-records.d.ts +4 -0
- package/src/lib/jobs/ai-workflow-records.js +40 -1
- package/src/lib/jobs/ai-workflow-records.js.map +1 -1
- package/src/lib/model/ai-automation-draft.d.ts +18 -0
- package/src/lib/model/ai-automation-draft.js +86 -0
- package/src/lib/model/ai-automation-draft.js.map +1 -1
- package/src/lib/model/ai-build-job.d.ts +201 -0
- package/src/lib/model/ai-build-job.js +471 -0
- package/src/lib/model/ai-build-job.js.map +1 -0
- package/src/lib/model/ai-build-plan.d.ts +61 -0
- package/src/lib/model/ai-build-plan.js +154 -9
- package/src/lib/model/ai-build-plan.js.map +1 -1
- package/src/lib/model/ai-build-progress.d.ts +56 -0
- package/src/lib/model/ai-build-progress.js +128 -0
- package/src/lib/model/ai-build-progress.js.map +1 -0
- package/src/lib/model/ai-insight.d.ts +20 -10
- package/src/lib/model/ai-insight.js +72 -9
- package/src/lib/model/ai-insight.js.map +1 -1
- package/src/lib/model/ai-job-activity.js +3 -1
- package/src/lib/model/ai-job-activity.js.map +1 -1
- package/src/lib/model/ai-job-failure-copy.d.ts +20 -1
- package/src/lib/model/ai-job-failure-copy.js +28 -1
- package/src/lib/model/ai-job-failure-copy.js.map +1 -1
- package/src/lib/model/ai-job-notice.d.ts +3 -0
- package/src/lib/model/ai-job-notice.js +11 -2
- package/src/lib/model/ai-job-notice.js.map +1 -1
- package/src/lib/model/ai-jobs.types.d.ts +87 -2
- package/src/lib/model/ai-jobs.types.js +3 -1
- package/src/lib/model/ai-jobs.types.js.map +1 -1
- package/src/lib/model/ai-logic-job.d.ts +108 -0
- package/src/lib/model/ai-logic-job.js +327 -0
- package/src/lib/model/ai-logic-job.js.map +1 -0
- package/src/lib/model/ai-media-credits.d.ts +52 -0
- package/src/lib/model/ai-media-credits.js +61 -0
- package/src/lib/model/ai-media-credits.js.map +1 -0
- package/src/lib/model/ai-overlay-copy.d.ts +114 -0
- package/src/lib/model/ai-overlay-copy.js +175 -0
- package/src/lib/model/ai-overlay-copy.js.map +1 -0
- package/src/lib/model/ai-site-build-progress.d.ts +28 -3
- package/src/lib/model/ai-site-build-progress.js +231 -17
- package/src/lib/model/ai-site-build-progress.js.map +1 -1
- package/src/lib/model/ai-site-start-seo.d.ts +16 -0
- package/src/lib/model/ai-site-start-seo.js +54 -4
- package/src/lib/model/ai-site-start-seo.js.map +1 -1
- package/src/lib/model/ai-site-start.d.ts +14 -0
- package/src/lib/model/ai-site-start.js +43 -0
- package/src/lib/model/ai-site-start.js.map +1 -1
- package/src/lib/model/ai-svg.d.ts +69 -0
- package/src/lib/model/ai-svg.js +265 -0
- package/src/lib/model/ai-svg.js.map +1 -0
- package/src/lib/model/ai-usage-by-user.d.ts +3 -2
- package/src/lib/model/ai-usage-by-user.js.map +1 -1
- package/src/lib/model/ai-workflow-job.d.ts +92 -4
- package/src/lib/model/ai-workflow-job.js +124 -7
- package/src/lib/model/ai-workflow-job.js.map +1 -1
- package/src/lib/model/assist-build.d.ts +58 -0
- package/src/lib/model/assist-build.js +52 -0
- package/src/lib/model/assist-build.js.map +1 -0
- package/src/lib/model/assist-edit.d.ts +48 -3
- package/src/lib/model/assist-edit.js +48 -4
- package/src/lib/model/assist-edit.js.map +1 -1
- package/src/lib/plugin-config.js +2 -0
- package/src/lib/plugin-config.js.map +1 -1
- package/src/lib/plugin.js +240 -11
- package/src/lib/plugin.js.map +1 -1
- package/src/lib/providers/catalog.d.ts +81 -4
- package/src/lib/providers/catalog.js +80 -9
- package/src/lib/providers/catalog.js.map +1 -1
- package/src/lib/providers/image-contract.d.ts +116 -0
- package/src/lib/providers/image-contract.js +74 -0
- package/src/lib/providers/image-contract.js.map +1 -0
- package/src/lib/providers/model-choice.js +11 -0
- package/src/lib/providers/model-choice.js.map +1 -1
- package/src/lib/providers/routing.js +18 -0
- package/src/lib/providers/routing.js.map +1 -1
- package/src/lib/providers/vertex-image.d.ts +121 -0
- package/src/lib/providers/vertex-image.js +312 -0
- package/src/lib/providers/vertex-image.js.map +1 -0
- package/src/lib/runtime/ai-doctrine-validators.d.ts +19 -0
- package/src/lib/runtime/ai-doctrine-validators.js +89 -0
- package/src/lib/runtime/ai-doctrine-validators.js.map +1 -1
- package/src/lib/runtime/ai-doctrine.d.ts +6 -0
- package/src/lib/runtime/ai-doctrine.js +16 -6
- package/src/lib/runtime/ai-doctrine.js.map +1 -1
- package/src/lib/runtime/ai-eval-live.js +4 -0
- package/src/lib/runtime/ai-eval-live.js.map +1 -1
- package/src/lib/runtime/ai-eval.d.ts +15 -1
- package/src/lib/runtime/ai-eval.js +52 -1
- package/src/lib/runtime/ai-eval.js.map +1 -1
- package/src/lib/runtime/experiment-variant-copy.d.ts +34 -0
- package/src/lib/runtime/experiment-variant-copy.js +102 -0
- package/src/lib/runtime/experiment-variant-copy.js.map +1 -0
- package/src/lib/server/ai-experiment-versions.d.ts +51 -0
- package/src/lib/server/ai-experiment-versions.js +270 -0
- package/src/lib/server/ai-experiment-versions.js.map +1 -0
- package/src/lib/server/ai-jobs-resume.js +74 -4
- package/src/lib/server/ai-jobs-resume.js.map +1 -1
- package/src/lib/server/ai-media-image.d.ts +66 -0
- package/src/lib/server/ai-media-image.js +521 -0
- package/src/lib/server/ai-media-image.js.map +1 -0
- package/src/lib/server/ai-media-svg.d.ts +91 -0
- package/src/lib/server/ai-media-svg.js +186 -0
- package/src/lib/server/ai-media-svg.js.map +1 -0
- package/src/lib/server/assist-build.d.ts +54 -0
- package/src/lib/server/assist-build.js +121 -0
- package/src/lib/server/assist-build.js.map +1 -0
- package/src/lib/server/assist-chat.js +108 -12
- package/src/lib/server/assist-chat.js.map +1 -1
- package/src/lib/server/assist-edit.js +213 -3
- package/src/lib/server/assist-edit.js.map +1 -1
- package/src/lib/server/assist-view-context.js +242 -4
- package/src/lib/server/assist-view-context.js.map +1 -1
- package/src/lib/server.js +26 -0
- package/src/lib/server.js.map +1 -1
- package/src/lib/tools/ai-logic-tool.d.ts +27 -0
- package/src/lib/tools/ai-logic-tool.js +207 -0
- package/src/lib/tools/ai-logic-tool.js.map +1 -0
- package/src/lib/tools/ai-overlay-tool.d.ts +35 -0
- package/src/lib/tools/ai-overlay-tool.js +107 -0
- package/src/lib/tools/ai-overlay-tool.js.map +1 -0
- package/src/lib/tools/ai-workflow-tool.d.ts +11 -0
- package/src/lib/tools/ai-workflow-tool.js +31 -0
- package/src/lib/tools/ai-workflow-tool.js.map +1 -1
- package/src/lib/usage/assist-job-refund.d.ts +31 -3
- package/src/lib/usage/assist-job-refund.js +46 -10
- package/src/lib/usage/assist-job-refund.js.map +1 -1
- package/src/lib/usage/assist-usage.d.ts +5 -0
- package/src/lib/usage/assist-usage.js +2 -0
- package/src/lib/usage/assist-usage.js.map +1 -1
|
@@ -17,17 +17,18 @@ import { _ as _extends } from "@swc/helpers/_/_extends";
|
|
|
17
17
|
*/ import { ACTION_MAX_CONDITIONS, ACTION_MAX_STEPS } from "@aglyn/aglyn/app-utils/site-interactions";
|
|
18
18
|
import { CONTACT_LIFECYCLE_STAGES, CONTACT_TAG_MAX_LENGTH, CRM_TASK_MAX_DUE_DAYS } from "@aglyn/aglyn/app-utils/crm";
|
|
19
19
|
import { HOST_EVENT_PAYLOAD_KEYS } from "@aglyn/aglyn/app-utils/host-events";
|
|
20
|
-
import {
|
|
20
|
+
import { checkEntitlement } from "@aglyn/aglyn/app-utils/plan-entitlements";
|
|
21
|
+
import { isHostPluginEnabled, isPluginEnabled } from "@aglyn/aglyn/plugin-manager/enabled-plugins";
|
|
21
22
|
import { filterEnabledPluginsByReleaseFlags } from "@aglyn/tenant-data-admin/server/release-flags";
|
|
22
23
|
import { resolveOrgIdForHost } from "@aglyn/tenant-data-admin/server/organizations";
|
|
23
|
-
import { aiAutomationDraft, aiAutomationDraftNote } from "../model/ai-automation-draft.js";
|
|
24
|
+
import { aiAutomationDraft, aiAutomationDraftNote, aiAutomationRevisionChanges, aiAutomationRevisionNote } from "../model/ai-automation-draft.js";
|
|
24
25
|
import { AI_AUTOMATION_TIMED_OUT_FIELD, AI_AUTOMATION_WAIT_MINUTES, aiStepLabel } from "../model/ai-automation-format.js";
|
|
25
26
|
import { aiActionOutline, aiActionRecordKinds, aiRunOutline, aiWorkflowExplanationText, aiWorkflowOutline } from "../model/ai-automation-outline.js";
|
|
26
|
-
import { AI_AUTOMATION_NEED_LABELS, AI_AUTOMATION_RESOURCE, AI_AUTOMATION_STEP_NEEDS, AI_AUTOMATION_STEP_TYPES, AI_AUTOMATION_TRIGGER_NEEDS, AI_AUTOMATION_TRIGGERS, AI_AUTOMATION_UNSUPPORTED_COPY, AI_WORKFLOW_GONE_COPY, AI_WORKFLOW_NO_DRAFT_COPY, AI_WORKFLOW_NO_EXPLANATION_COPY, AI_WORKFLOW_NO_SITE_COPY, AI_WORKFLOW_RUN_GONE_COPY, AI_WORKFLOW_RUN_NOT_FAILED_COPY, AI_WORKFLOW_SAVE_FAILURE_COPY, AI_WORKFLOW_UNAVAILABLE_COPY, aiAutomationCapabilities, aiAutomationTriggerLabel, parseAiWorkflowJobInputs } from "../model/ai-workflow-job.js";
|
|
27
|
+
import { AI_AUTOMATION_NEED_LABELS, AI_AUTOMATION_RESOURCE, AI_AUTOMATION_STEP_NEEDS, AI_AUTOMATION_STEP_TYPES, AI_AUTOMATION_TRIGGER_NEEDS, AI_AUTOMATION_TRIGGERS, AI_AUTOMATION_UNSUPPORTED_COPY, AI_WORKFLOW_GONE_COPY, AI_WORKFLOW_NO_DRAFT_COPY, AI_WORKFLOW_NO_EXPLANATION_COPY, AI_WORKFLOW_NO_SITE_COPY, AI_WORKFLOW_RUN_GONE_COPY, AI_WORKFLOW_RUN_NOT_FAILED_COPY, AI_WORKFLOW_SAVE_FAILURE_COPY, AI_WORKFLOW_REVISE_BLOCKER_COPY, AI_WORKFLOW_REVISE_WORKFLOW_COPY, AI_WORKFLOW_UNAVAILABLE_COPY, AI_ORG_AUTOMATION_PLAN_COPY, AI_ORG_AUTOMATION_RESOURCE, AI_ORG_AUTOMATION_UNAVAILABLE_COPY, aiActionReviseBlocker, aiAutomationCapabilities, aiAutomationTriggerLabel, parseAiWorkflowJobInputs } from "../model/ai-workflow-job.js";
|
|
27
28
|
import { AI_STEP_TIERS } from "../providers/catalog.js";
|
|
28
29
|
import { AI_ROUTING_TABLE, aiModelForStep } from "../providers/routing.js";
|
|
29
30
|
import { runValidatedGeneration } from "../runtime/ai-doctrine.js";
|
|
30
|
-
import { AI_AUTOMATION_TOOL_NAME, AI_WORKFLOW_EXPLANATION_TOOL_NAME, aiAutomationTool, aiWorkflowExplanationTool, readAiAutomationAnswer, readAiWorkflowExplanation } from "../tools/ai-workflow-tool.js";
|
|
31
|
+
import { AI_AUTOMATION_TOOL_NAME, AI_WORKFLOW_EXPLANATION_TOOL_NAME, aiAutomationTool, aiWorkflowExplanationTool, holdAiAutomationAnswerToVocabulary, readAiAutomationAnswer, readAiWorkflowExplanation } from "../tools/ai-workflow-tool.js";
|
|
31
32
|
import { registerAiJobAdmission } from "./ai-job-admission.js";
|
|
32
33
|
import { aiJobStepBudget } from "./ai-job-budget.js";
|
|
33
34
|
import { aiJobDraftId } from "./ai-job-draft-ids.js";
|
|
@@ -35,7 +36,7 @@ import { aiDoctrineReview, aiGenerationSpent, aiLimitReview, aiUnspentOutcome }
|
|
|
35
36
|
import { aiPluginDraftAdmissionRefusal, aiPluginDraftOwner, aiPluginDraftUnavailable, aiPluginDraftWriter } from "./ai-job-plugin-drafts.js";
|
|
36
37
|
import { AI_JOB_BRIEF_MAX_CHARS } from "./ai-job-text-step.js";
|
|
37
38
|
import { registerAiJobStep } from "./ai-jobs.js";
|
|
38
|
-
import { readAiAutomationRecords, readAiWorkflowFunctions, readAiWorkflowRun, readAiWorkflowTarget } from "./ai-workflow-records.js";
|
|
39
|
+
import { readAiAutomationRecords, readAiOrgAutomationRecords, readAiWorkflowFunctions, readAiWorkflowRun, readAiWorkflowTarget } from "./ai-workflow-records.js";
|
|
39
40
|
/**
|
|
40
41
|
* The `workflow` step (AGL-2919): an automation drafted from a description,
|
|
41
42
|
* or a saved automation explained.
|
|
@@ -68,6 +69,29 @@ import { readAiAutomationRecords, readAiWorkflowFunctions, readAiWorkflowRun, re
|
|
|
68
69
|
* never the stored documents, never an email address, never a run's event
|
|
69
70
|
* payload. It answers through `submit_explanation`, which becomes a `text`
|
|
70
71
|
* output. Nothing is changed.
|
|
72
|
+
*
|
|
73
|
+
* ## Revising (AGL-3603)
|
|
74
|
+
*
|
|
75
|
+
* A saved ACTION and a change asked of it. The model is sent the drafting
|
|
76
|
+
* request — the same cached vocabulary, the same tool, the same reach, forms
|
|
77
|
+
* and datasets — with the action's outline in the user turn and the change as
|
|
78
|
+
* the brief, and answers the whole action as it would be after the change.
|
|
79
|
+
* That answer is held to the vocabulary and matched to the site's records as
|
|
80
|
+
* a draft is, and written as a NEW draft, OFF, under the job's draft id: the
|
|
81
|
+
* saved action is read and never written. What changed is worked out in code
|
|
82
|
+
* from the two stored shapes. An action holding what the vocabulary cannot
|
|
83
|
+
* write is refused before the model is asked, so a revision never drops an
|
|
84
|
+
* on-page step the person did not ask to lose.
|
|
85
|
+
*
|
|
86
|
+
* ## A workspace's automation (AGL-3603)
|
|
87
|
+
*
|
|
88
|
+
* A draft with `scope: 'org'` names no site. It is asked as a draft is — the
|
|
89
|
+
* same cached vocabulary, the same tool — with the org automation's narrower
|
|
90
|
+
* vocabulary stated in the user turn and held by the check, and matched
|
|
91
|
+
* against the workspace's lists, campaigns, datasets and stages. Nothing is
|
|
92
|
+
* written: the automation rides on an `orgAutomation` output, which the Org
|
|
93
|
+
* automations editor opens unsaved, where its sites are picked and its save
|
|
94
|
+
* route — the workflows plugin's — holds it to that plugin's rules.
|
|
71
95
|
*/ /** The longest an explanation or a draft's generation may take reading the site first. */ export const AI_WORKFLOW_RECORDS_READ_MS = 4000;
|
|
72
96
|
/**
|
|
73
97
|
* The step's time (AGL-3035): its answer and its re-ask at the routing
|
|
@@ -174,21 +198,41 @@ function stepLine(type) {
|
|
|
174
198
|
function yesNo(value) {
|
|
175
199
|
return value ? 'yes' : 'no';
|
|
176
200
|
}
|
|
177
|
-
/**
|
|
201
|
+
/**
|
|
202
|
+
* What a draft is asked from: the workspace's reach, the site's forms and
|
|
203
|
+
* datasets, and the brief. A revision adds the saved action's outline, and its
|
|
204
|
+
* brief is the change asked for.
|
|
205
|
+
*/ export function aiJobWorkflowDraftPrompt(input) {
|
|
178
206
|
const { crm, webhooks, bookings } = input.capabilities;
|
|
179
207
|
const forms = input.records.forms.slice(0, AI_WORKFLOW_FORMS_LISTED);
|
|
180
208
|
const datasets = input.records.datasets.slice(0, AI_WORKFLOW_DATASETS_LISTED);
|
|
181
209
|
return [
|
|
210
|
+
...input.org ? [
|
|
211
|
+
'This automation belongs to the workspace: it runs on each site it is placed on, as that site. It may start only on these triggers, and use only these steps; anything else, even if listed above, is never used.',
|
|
212
|
+
`Triggers: ${input.org.triggers.join(', ')}.`,
|
|
213
|
+
`Steps: ${input.org.steps.join(', ')}.`
|
|
214
|
+
] : [],
|
|
182
215
|
`This workspace can use: the CRM — ${yesNo(crm)}; webhooks — ${yesNo(webhooks)}; bookings — ${yesNo(bookings)}.`,
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
216
|
+
...input.org ? [
|
|
217
|
+
'Forms: an automation of the workspace runs on several sites, so none is listed; a form is named in the description’s words.'
|
|
218
|
+
] : [
|
|
219
|
+
'Forms on this site (id · name · fields):',
|
|
220
|
+
...forms.length ? forms.map((form)=>`- ${form.id} · ${form.name} · ${form.fields.slice(0, AI_WORKFLOW_FORM_FIELDS_LISTED).join(', ') || 'no fields'}`) : [
|
|
221
|
+
'- none'
|
|
222
|
+
]
|
|
186
223
|
],
|
|
187
|
-
'Datasets on this site (name):',
|
|
224
|
+
input.org ? 'Datasets in this workspace (name):' : 'Datasets on this site (name):',
|
|
188
225
|
...datasets.length ? datasets.map((dataset)=>`- ${dataset.name}`) : [
|
|
189
226
|
'- none'
|
|
190
227
|
],
|
|
191
|
-
|
|
228
|
+
...input.revising ? [
|
|
229
|
+
'The automation to change, as it is set up now:',
|
|
230
|
+
input.revising.outline,
|
|
231
|
+
'Answer with the whole automation as it should be after the change below. Keep every condition and step the change does not touch as it is, with the same records named in the same words, and keep its name unless the change asks for another. A detail shown as [email address] or a named teammate is written as a placeholder in square brackets.',
|
|
232
|
+
`Change: ${input.brief.slice(0, AI_JOB_BRIEF_MAX_CHARS)}`
|
|
233
|
+
] : [
|
|
234
|
+
`Brief: ${input.brief.slice(0, AI_JOB_BRIEF_MAX_CHARS)}`
|
|
235
|
+
]
|
|
192
236
|
].join('\n');
|
|
193
237
|
}
|
|
194
238
|
/** What an explanation is asked from: the mode, the outlines, and the member's question. */ export function aiJobWorkflowExplainPrompt(input) {
|
|
@@ -210,7 +254,8 @@ function yesNo(value) {
|
|
|
210
254
|
} : {});
|
|
211
255
|
}
|
|
212
256
|
/** The draft generation as the doctrine's loop runs it; the eval harness records one through this same call. */ export function aiJobWorkflowDraftGeneration(request) {
|
|
213
|
-
const
|
|
257
|
+
const org = request.org;
|
|
258
|
+
const check = (answer)=>org ? holdAiAutomationAnswerToVocabulary(readAiAutomationAnswer(answer, request.capabilities), org) : readAiAutomationAnswer(answer, request.capabilities);
|
|
214
259
|
return _extends({
|
|
215
260
|
step: 'job.workflow',
|
|
216
261
|
model: request.model,
|
|
@@ -253,9 +298,10 @@ function yesNo(value) {
|
|
|
253
298
|
return `“${clean.length > 60 ? `${clean.slice(0, 60)}…` : clean}”`;
|
|
254
299
|
}
|
|
255
300
|
export function createAiJobWorkflowStep(deps = {}) {
|
|
256
|
-
var _deps_writerFor, _deps_readRecords, _deps_readTarget, _deps_readRun, _deps_readFunctions;
|
|
301
|
+
var _deps_writerFor, _deps_readRecords, _deps_readOrgRecords, _deps_readTarget, _deps_readRun, _deps_readFunctions;
|
|
257
302
|
const writerFor = (_deps_writerFor = deps.writerFor) != null ? _deps_writerFor : aiPluginDraftWriter;
|
|
258
303
|
const readRecords = (_deps_readRecords = deps.readRecords) != null ? _deps_readRecords : readAiAutomationRecords;
|
|
304
|
+
const readOrgRecords = (_deps_readOrgRecords = deps.readOrgRecords) != null ? _deps_readOrgRecords : readAiOrgAutomationRecords;
|
|
259
305
|
const readTarget = (_deps_readTarget = deps.readTarget) != null ? _deps_readTarget : readAiWorkflowTarget;
|
|
260
306
|
const readRun = (_deps_readRun = deps.readRun) != null ? _deps_readRun : readAiWorkflowRun;
|
|
261
307
|
const readFunctions = (_deps_readFunctions = deps.readFunctions) != null ? _deps_readFunctions : readAiWorkflowFunctions;
|
|
@@ -268,6 +314,58 @@ export function createAiJobWorkflowStep(deps = {}) {
|
|
|
268
314
|
});
|
|
269
315
|
const inputs = parseAiWorkflowJobInputs(job.inputs);
|
|
270
316
|
if (typeof inputs === 'string') return unspent(inputs);
|
|
317
|
+
if (inputs.mode === 'draft' && inputs.scope === 'org') {
|
|
318
|
+
var _ref2;
|
|
319
|
+
// A workspace's automation (AGL-3603): no site, and nothing written.
|
|
320
|
+
const orgData = (_ref2 = org != null ? org : (await firestore.collection('orgs').doc(job.orgId).get()).data()) != null ? _ref2 : null;
|
|
321
|
+
if (!checkEntitlement(orgData, 'actions')) {
|
|
322
|
+
return aiUnspentOutcome(model, {
|
|
323
|
+
review: aiLimitReview(AI_ORG_AUTOMATION_PLAN_COPY)
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
const capabilities = aiAutomationCapabilities(orgData);
|
|
327
|
+
const vocabulary = {
|
|
328
|
+
triggers: inputs.triggers,
|
|
329
|
+
steps: inputs.steps
|
|
330
|
+
};
|
|
331
|
+
const records = await readOrgRecords(firestore, {
|
|
332
|
+
orgId: job.orgId,
|
|
333
|
+
crm: capabilities.crm
|
|
334
|
+
});
|
|
335
|
+
const generation = await runValidatedGeneration('workflow', aiJobWorkflowDraftGeneration(_extends({
|
|
336
|
+
brief: job.brief,
|
|
337
|
+
capabilities,
|
|
338
|
+
records,
|
|
339
|
+
org: vocabulary,
|
|
340
|
+
model
|
|
341
|
+
}, signal ? {
|
|
342
|
+
signal
|
|
343
|
+
} : {})));
|
|
344
|
+
const spent = _extends({}, aiGenerationSpent(generation), generation.effort ? {
|
|
345
|
+
effort: generation.effort
|
|
346
|
+
} : {});
|
|
347
|
+
if (generation.status === 'refused') return _extends({}, spent, {
|
|
348
|
+
refused: true
|
|
349
|
+
});
|
|
350
|
+
if (generation.status === 'needs_input') return _extends({}, spent, {
|
|
351
|
+
review: aiDoctrineReview(generation)
|
|
352
|
+
});
|
|
353
|
+
const answer = generation.value;
|
|
354
|
+
if (answer.unsupported) {
|
|
355
|
+
return _extends({}, spent, {
|
|
356
|
+
failure: answer.unsupported === 'no-trigger' || answer.unsupported === 'no-step' ? AI_ORG_AUTOMATION_UNSUPPORTED_COPY : AI_AUTOMATION_UNSUPPORTED_COPY[answer.unsupported]
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
if (!answer.steps.length) return _extends({}, spent, {
|
|
360
|
+
failure: AI_WORKFLOW_NO_DRAFT_COPY
|
|
361
|
+
});
|
|
362
|
+
const draft = aiAutomationDraft(answer, records);
|
|
363
|
+
return _extends({}, spent, {
|
|
364
|
+
outputs: [
|
|
365
|
+
orgProposalOutput(draft, answer.notes)
|
|
366
|
+
]
|
|
367
|
+
});
|
|
368
|
+
}
|
|
271
369
|
const hostId = job.hostId;
|
|
272
370
|
if (!hostId) return unspent(AI_WORKFLOW_NO_SITE_COPY);
|
|
273
371
|
// The door checks the caller's membership of the org the job is metered
|
|
@@ -362,6 +460,111 @@ export function createAiJobWorkflowStep(deps = {}) {
|
|
|
362
460
|
]
|
|
363
461
|
});
|
|
364
462
|
}
|
|
463
|
+
if (inputs.mode === 'revise') {
|
|
464
|
+
const writer = writerFor(AI_AUTOMATION_RESOURCE);
|
|
465
|
+
if (!writer) return unspent(AI_WORKFLOW_UNAVAILABLE_COPY);
|
|
466
|
+
const place = {
|
|
467
|
+
hostId,
|
|
468
|
+
hostSubdomain
|
|
469
|
+
};
|
|
470
|
+
const draftId = aiJobDraftId(job, 'workflow');
|
|
471
|
+
const written = await writer.read({
|
|
472
|
+
hostId,
|
|
473
|
+
id: draftId
|
|
474
|
+
});
|
|
475
|
+
if (written) {
|
|
476
|
+
return aiUnspentOutcome(model, {
|
|
477
|
+
outputs: [
|
|
478
|
+
draftOutput(written.id, written.name, place, 'It is off until you switch it on.')
|
|
479
|
+
]
|
|
480
|
+
});
|
|
481
|
+
}
|
|
482
|
+
const saved = await readTarget({
|
|
483
|
+
hostId,
|
|
484
|
+
type: 'action',
|
|
485
|
+
id: inputs.targetId
|
|
486
|
+
});
|
|
487
|
+
if (!saved) return unspent(AI_WORKFLOW_GONE_COPY);
|
|
488
|
+
if (saved.type !== 'action') return unspent(AI_WORKFLOW_REVISE_WORKFLOW_COPY);
|
|
489
|
+
const blocker = aiActionReviseBlocker(saved.action);
|
|
490
|
+
if (blocker) return unspent(AI_WORKFLOW_REVISE_BLOCKER_COPY[blocker]);
|
|
491
|
+
const context = {
|
|
492
|
+
orgId: job.orgId,
|
|
493
|
+
hostId,
|
|
494
|
+
uid: job.createdBy,
|
|
495
|
+
org: orgData,
|
|
496
|
+
now
|
|
497
|
+
};
|
|
498
|
+
const refusal = await writer.refusal(context);
|
|
499
|
+
if (refusal) {
|
|
500
|
+
return refusal.status === 403 ? aiUnspentOutcome(model, {
|
|
501
|
+
review: aiLimitReview(refusal.error)
|
|
502
|
+
}) : unspent(refusal.error);
|
|
503
|
+
}
|
|
504
|
+
const records = await readRecords(firestore, {
|
|
505
|
+
orgId: job.orgId,
|
|
506
|
+
hostId,
|
|
507
|
+
crm: capabilities.crm
|
|
508
|
+
});
|
|
509
|
+
const generation = await runValidatedGeneration('workflow', aiJobWorkflowDraftGeneration(_extends({
|
|
510
|
+
brief: job.brief,
|
|
511
|
+
capabilities,
|
|
512
|
+
records,
|
|
513
|
+
revising: {
|
|
514
|
+
outline: aiActionOutline(saved.action, records)
|
|
515
|
+
},
|
|
516
|
+
model
|
|
517
|
+
}, signal ? {
|
|
518
|
+
signal
|
|
519
|
+
} : {})));
|
|
520
|
+
const spent = _extends({}, aiGenerationSpent(generation), generation.effort ? {
|
|
521
|
+
effort: generation.effort
|
|
522
|
+
} : {});
|
|
523
|
+
if (generation.status === 'refused') return _extends({}, spent, {
|
|
524
|
+
refused: true
|
|
525
|
+
});
|
|
526
|
+
if (generation.status === 'needs_input') return _extends({}, spent, {
|
|
527
|
+
review: aiDoctrineReview(generation)
|
|
528
|
+
});
|
|
529
|
+
const answer = generation.value;
|
|
530
|
+
if (answer.unsupported) return _extends({}, spent, {
|
|
531
|
+
failure: AI_AUTOMATION_UNSUPPORTED_COPY[answer.unsupported]
|
|
532
|
+
});
|
|
533
|
+
if (!answer.steps.length) return _extends({}, spent, {
|
|
534
|
+
failure: AI_WORKFLOW_NO_DRAFT_COPY
|
|
535
|
+
});
|
|
536
|
+
const draft = aiAutomationDraft(answer, records);
|
|
537
|
+
// The copy never takes the saved action's name: two rows by one name
|
|
538
|
+
// in the list are two rows nobody can tell apart.
|
|
539
|
+
const name = draft.action.name.trim() && draft.action.name.trim() !== saved.name.trim() ? draft.action.name : aiRevisedName(saved.name);
|
|
540
|
+
const write = await writer.write(_extends({}, context, {
|
|
541
|
+
id: draftId,
|
|
542
|
+
name,
|
|
543
|
+
content: {
|
|
544
|
+
action: _extends({}, draft.action, {
|
|
545
|
+
name
|
|
546
|
+
})
|
|
547
|
+
}
|
|
548
|
+
}));
|
|
549
|
+
if (write.ok === false) {
|
|
550
|
+
return write.status === 403 ? _extends({}, spent, {
|
|
551
|
+
review: aiLimitReview(write.error)
|
|
552
|
+
}) : _extends({}, spent, {
|
|
553
|
+
failure: AI_WORKFLOW_SAVE_FAILURE_COPY
|
|
554
|
+
});
|
|
555
|
+
}
|
|
556
|
+
const changes = aiAutomationRevisionChanges(saved.action, draft.action, aiStepLabel);
|
|
557
|
+
return _extends({}, spent, {
|
|
558
|
+
outputs: [
|
|
559
|
+
draftOutput(write.id, write.name, place, aiAutomationRevisionNote({
|
|
560
|
+
fromName: saved.name,
|
|
561
|
+
changes,
|
|
562
|
+
draft,
|
|
563
|
+
notes: answer.notes
|
|
564
|
+
}))
|
|
565
|
+
]
|
|
566
|
+
});
|
|
567
|
+
}
|
|
365
568
|
const target = await readTarget({
|
|
366
569
|
hostId,
|
|
367
570
|
type: inputs.targetType,
|
|
@@ -423,6 +626,41 @@ export function createAiJobWorkflowStep(deps = {}) {
|
|
|
423
626
|
});
|
|
424
627
|
};
|
|
425
628
|
}
|
|
629
|
+
/** What a person is told when a workspace's automation would need what only one site runs. */ export const AI_ORG_AUTOMATION_UNSUPPORTED_COPY = 'An org automation cannot do what this description asks — it starts only on what the server sees and uses only the steps every site runs the same way — so nothing was drafted. Build it as an action on the site instead.';
|
|
630
|
+
/**
|
|
631
|
+
* A workspace's drafted automation as the output that proposes it
|
|
632
|
+
* (AGL-3603): the stored shape the Org automations editor opens — its name,
|
|
633
|
+
* trigger and steps, never a placement, which the person picks — and what
|
|
634
|
+
* to fill in before switching it on.
|
|
635
|
+
*/ export function orgProposalOutput(draft, notes) {
|
|
636
|
+
const { name, trigger, steps } = draft.action;
|
|
637
|
+
return {
|
|
638
|
+
resource: AI_ORG_AUTOMATION_RESOURCE,
|
|
639
|
+
// A proposal has no document; the id names what it is within the job.
|
|
640
|
+
id: 'proposal',
|
|
641
|
+
hostId: null,
|
|
642
|
+
hostSubdomain: null,
|
|
643
|
+
label: name,
|
|
644
|
+
note: [
|
|
645
|
+
'Nothing is saved yet: it opens in the org automation editor, switched off, where you choose the sites it runs on and save it.',
|
|
646
|
+
...draft.placeholders.length ? [
|
|
647
|
+
`Fill in ${draft.placeholders.length === 1 ? 'its placeholder' : `its ${draft.placeholders.length} placeholders`} before switching it on.`
|
|
648
|
+
] : [],
|
|
649
|
+
...notes
|
|
650
|
+
].join(' '),
|
|
651
|
+
proposal: {
|
|
652
|
+
automation: {
|
|
653
|
+
name,
|
|
654
|
+
trigger,
|
|
655
|
+
steps
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
};
|
|
659
|
+
}
|
|
660
|
+
/** The name a revised copy is saved under when the change asked for no other. */ export function aiRevisedName(name) {
|
|
661
|
+
const clean = name.replace(/\s+/g, ' ').trim() || 'Automation';
|
|
662
|
+
return `${clean.length > 80 ? clean.slice(0, 80) : clean} (revised)`;
|
|
663
|
+
}
|
|
426
664
|
function draftOutput(id, name, place, note) {
|
|
427
665
|
return {
|
|
428
666
|
resource: 'workflow',
|
|
@@ -460,6 +698,40 @@ export const runAiJobWorkflowStep = createAiJobWorkflowStep();
|
|
|
460
698
|
error: aiPluginDraftUnavailable('Automation')
|
|
461
699
|
};
|
|
462
700
|
}
|
|
701
|
+
/**
|
|
702
|
+
* Whether a workspace's automation may be drafted (AGL-3603): no site is
|
|
703
|
+
* named, the plugin that keeps automations runs for the workspace and is
|
|
704
|
+
* past its release flag, and the plan includes the actions builder that
|
|
705
|
+
* section is sold under. Nothing is written, so no allowance is asked: the
|
|
706
|
+
* section's save route counts its cap when the person saves.
|
|
707
|
+
*/ async function orgAutomationRefusal(context) {
|
|
708
|
+
if (context.hostId) return {
|
|
709
|
+
status: 400,
|
|
710
|
+
error: 'An org automation belongs to no one site'
|
|
711
|
+
};
|
|
712
|
+
const owner = aiPluginDraftOwner(AI_AUTOMATION_RESOURCE);
|
|
713
|
+
if (!owner) return {
|
|
714
|
+
status: 403,
|
|
715
|
+
error: AI_ORG_AUTOMATION_UNAVAILABLE_COPY
|
|
716
|
+
};
|
|
717
|
+
const org = context.org;
|
|
718
|
+
const released = await filterEnabledPluginsByReleaseFlags([
|
|
719
|
+
owner
|
|
720
|
+
], {
|
|
721
|
+
orgId: context.orgId,
|
|
722
|
+
authorization: null
|
|
723
|
+
});
|
|
724
|
+
if (!released.includes(owner) || !isPluginEnabled(org, owner)) {
|
|
725
|
+
return {
|
|
726
|
+
status: 403,
|
|
727
|
+
error: AI_ORG_AUTOMATION_UNAVAILABLE_COPY
|
|
728
|
+
};
|
|
729
|
+
}
|
|
730
|
+
return checkEntitlement(org, 'actions') ? null : {
|
|
731
|
+
status: 403,
|
|
732
|
+
error: AI_ORG_AUTOMATION_PLAN_COPY
|
|
733
|
+
};
|
|
734
|
+
}
|
|
463
735
|
/**
|
|
464
736
|
* A workflow job is admitted for a site of its org with the Automation plugin
|
|
465
737
|
* on. A draft also needs the draft writer and the member's room and role in
|
|
@@ -475,6 +747,7 @@ export const runAiJobWorkflowStep = createAiJobWorkflowStep();
|
|
|
475
747
|
status: 400,
|
|
476
748
|
error: inputs
|
|
477
749
|
};
|
|
750
|
+
if (inputs.mode === 'draft' && inputs.scope === 'org') return orgAutomationRefusal(context);
|
|
478
751
|
if (inputs.mode === 'draft') {
|
|
479
752
|
return aiPluginDraftAdmissionRefusal(context, _extends({
|
|
480
753
|
kind: 'workflow',
|
|
@@ -488,6 +761,38 @@ export const runAiJobWorkflowStep = createAiJobWorkflowStep();
|
|
|
488
761
|
writerFor: deps.writerFor
|
|
489
762
|
} : {}));
|
|
490
763
|
}
|
|
764
|
+
if (inputs.mode === 'revise') {
|
|
765
|
+
// A revision writes a draft as a description does, and also needs the
|
|
766
|
+
// action it starts from to exist and to hold only what AI writes.
|
|
767
|
+
return aiPluginDraftAdmissionRefusal(context, _extends({
|
|
768
|
+
kind: 'workflow',
|
|
769
|
+
drafts: [
|
|
770
|
+
{
|
|
771
|
+
resource: AI_AUTOMATION_RESOURCE,
|
|
772
|
+
label: 'Automation'
|
|
773
|
+
}
|
|
774
|
+
]
|
|
775
|
+
}, deps.writerFor ? {
|
|
776
|
+
writerFor: deps.writerFor
|
|
777
|
+
} : {}, {
|
|
778
|
+
ownCheck: async (hostId)=>{
|
|
779
|
+
const saved = await readTarget({
|
|
780
|
+
hostId,
|
|
781
|
+
type: 'action',
|
|
782
|
+
id: inputs.targetId
|
|
783
|
+
});
|
|
784
|
+
if (!saved || saved.type !== 'action') return {
|
|
785
|
+
status: 404,
|
|
786
|
+
error: AI_WORKFLOW_GONE_COPY
|
|
787
|
+
};
|
|
788
|
+
const blocker = aiActionReviseBlocker(saved.action);
|
|
789
|
+
return blocker ? {
|
|
790
|
+
status: 400,
|
|
791
|
+
error: AI_WORKFLOW_REVISE_BLOCKER_COPY[blocker]
|
|
792
|
+
} : null;
|
|
793
|
+
}
|
|
794
|
+
}));
|
|
795
|
+
}
|
|
491
796
|
const hostId = context.hostId;
|
|
492
797
|
if (!hostId) return {
|
|
493
798
|
status: 400,
|