@elevasis/sdk 1.16.0 → 1.18.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/dist/cli.cjs +382 -175
- package/dist/index.d.ts +390 -73
- package/dist/index.js +1087 -62
- package/dist/node/index.d.ts +3 -0
- package/dist/node/index.js +34 -1
- package/dist/test-utils/index.d.ts +108 -71
- package/dist/test-utils/index.js +1872 -667
- package/dist/types/worker/index.d.ts +3 -2
- package/dist/worker/index.js +1373 -2
- package/package.json +2 -2
- package/reference/claude-config/rules/package-taxonomy.md +33 -0
- package/reference/claude-config/rules/vibe.md +23 -0
- package/reference/claude-config/skills/knowledge/SKILL.md +37 -5
- package/reference/claude-config/skills/project/SKILL.md +21 -0
- package/reference/claude-config/skills/tutorial/SKILL.md +13 -3
- package/reference/claude-config/sync-notes/2026-05-04-knowledge-bundle.md +83 -0
- package/reference/claude-config/sync-notes/2026-05-05-list-builder.md +42 -0
- package/reference/claude-config/sync-notes/2026-05-06-sdk-changes-release-train.md +37 -0
- package/reference/scaffold/reference/contracts.md +78 -65
- package/reference/scaffold/reference/feature-registry.md +1 -1
- package/reference/spine/spine-primer.md +99 -0
package/dist/test-utils/index.js
CHANGED
|
@@ -5560,6 +5560,29 @@ function estimateTokens(text) {
|
|
|
5560
5560
|
const chars4 = content.length;
|
|
5561
5561
|
return Math.ceil(chars4 / 3.5);
|
|
5562
5562
|
}
|
|
5563
|
+
var UuidSchema = z.string().uuid();
|
|
5564
|
+
var NonEmptyStringSchema = z.string().trim().min(1).max(1e3);
|
|
5565
|
+
z.enum(["agent", "workflow"]);
|
|
5566
|
+
z.enum(["agent", "workflow", "scheduler", "api"]);
|
|
5567
|
+
z.string().trim().toLowerCase().min(1, "Credential name required").max(100, "Credential name too long (max 100 chars)").regex(
|
|
5568
|
+
/^[a-z0-9]+(-[a-z0-9]+)+$/,
|
|
5569
|
+
"Credential name must be lowercase letters, numbers, and hyphens in format: service-environment (e.g., gmail-prod, attio-dev)"
|
|
5570
|
+
);
|
|
5571
|
+
z.enum(["google-sheets", "google-calendar", "dropbox"]);
|
|
5572
|
+
z.string().min(10, "Authorization code too short").max(1e3, "Authorization code too long");
|
|
5573
|
+
z.string().min(10, "State parameter too short").max(2048, "State parameter too long");
|
|
5574
|
+
z.string().trim().transform((str) => str.replace(/[<>'"]/g, ""));
|
|
5575
|
+
z.string().email();
|
|
5576
|
+
z.string().url();
|
|
5577
|
+
z.object({
|
|
5578
|
+
limit: z.coerce.number().int().min(1).max(100).default(20),
|
|
5579
|
+
offset: z.coerce.number().int().min(0).default(0)
|
|
5580
|
+
});
|
|
5581
|
+
z.string().datetime();
|
|
5582
|
+
z.object({
|
|
5583
|
+
startDate: z.string().datetime(),
|
|
5584
|
+
endDate: z.string().datetime()
|
|
5585
|
+
});
|
|
5563
5586
|
|
|
5564
5587
|
// ../core/src/platform/constants/limits.ts
|
|
5565
5588
|
var MAX_SESSION_MEMORY_KEYS = 25;
|
|
@@ -6488,6 +6511,1167 @@ Fix the errors and generate a valid output.
|
|
|
6488
6511
|
}
|
|
6489
6512
|
}
|
|
6490
6513
|
};
|
|
6514
|
+
var ORGANIZATION_MODEL_ICON_TOKENS = [
|
|
6515
|
+
"nav.dashboard",
|
|
6516
|
+
"nav.calendar",
|
|
6517
|
+
"nav.sales",
|
|
6518
|
+
"nav.crm",
|
|
6519
|
+
"nav.lead-gen",
|
|
6520
|
+
"nav.projects",
|
|
6521
|
+
"nav.operations",
|
|
6522
|
+
"nav.monitoring",
|
|
6523
|
+
"nav.knowledge",
|
|
6524
|
+
"nav.settings",
|
|
6525
|
+
"nav.admin",
|
|
6526
|
+
"nav.archive",
|
|
6527
|
+
"knowledge.playbook",
|
|
6528
|
+
"knowledge.strategy",
|
|
6529
|
+
"knowledge.reference",
|
|
6530
|
+
"feature.dashboard",
|
|
6531
|
+
"feature.calendar",
|
|
6532
|
+
"feature.sales",
|
|
6533
|
+
"feature.crm",
|
|
6534
|
+
"feature.finance",
|
|
6535
|
+
"feature.lead-gen",
|
|
6536
|
+
"feature.platform",
|
|
6537
|
+
"feature.projects",
|
|
6538
|
+
"feature.operations",
|
|
6539
|
+
"feature.knowledge",
|
|
6540
|
+
"feature.monitoring",
|
|
6541
|
+
"feature.settings",
|
|
6542
|
+
"feature.admin",
|
|
6543
|
+
"feature.archive",
|
|
6544
|
+
"feature.seo",
|
|
6545
|
+
"resource.agent",
|
|
6546
|
+
"resource.workflow",
|
|
6547
|
+
"resource.integration",
|
|
6548
|
+
"resource.database",
|
|
6549
|
+
"resource.user",
|
|
6550
|
+
"resource.team",
|
|
6551
|
+
"integration.gmail",
|
|
6552
|
+
"integration.google-sheets",
|
|
6553
|
+
"integration.attio",
|
|
6554
|
+
"surface.dashboard",
|
|
6555
|
+
"surface.calendar",
|
|
6556
|
+
"surface.overview",
|
|
6557
|
+
"surface.command-view",
|
|
6558
|
+
"surface.command-queue",
|
|
6559
|
+
"surface.pipeline",
|
|
6560
|
+
"surface.lists",
|
|
6561
|
+
"surface.resources",
|
|
6562
|
+
"surface.settings",
|
|
6563
|
+
"status.success",
|
|
6564
|
+
"status.error",
|
|
6565
|
+
"status.warning",
|
|
6566
|
+
"status.info",
|
|
6567
|
+
"status.pending",
|
|
6568
|
+
"action.approve",
|
|
6569
|
+
"action.reject",
|
|
6570
|
+
"action.retry",
|
|
6571
|
+
"action.edit",
|
|
6572
|
+
"action.view",
|
|
6573
|
+
"action.launch",
|
|
6574
|
+
"action.message",
|
|
6575
|
+
"action.escalate",
|
|
6576
|
+
"action.promote",
|
|
6577
|
+
"action.submit",
|
|
6578
|
+
"action.email"
|
|
6579
|
+
];
|
|
6580
|
+
var CustomIconTokenSchema = z.string().trim().max(80).regex(/^custom\.[a-z0-9]+(?:[-._][a-z0-9]+)*$/, "Custom icon tokens must start with custom.");
|
|
6581
|
+
var OrganizationModelBuiltinIconTokenSchema = z.enum(ORGANIZATION_MODEL_ICON_TOKENS);
|
|
6582
|
+
var OrganizationModelIconTokenSchema = z.union([
|
|
6583
|
+
OrganizationModelBuiltinIconTokenSchema,
|
|
6584
|
+
CustomIconTokenSchema
|
|
6585
|
+
]);
|
|
6586
|
+
|
|
6587
|
+
// ../core/src/organization-model/domains/shared.ts
|
|
6588
|
+
var ModelIdSchema = z.string().trim().min(1).max(100).regex(/^[a-z0-9]+(?:[-._][a-z0-9]+)*$/, "IDs must be lowercase and use -, _, or . separators");
|
|
6589
|
+
var LabelSchema = z.string().trim().min(1).max(120);
|
|
6590
|
+
var DescriptionSchema = z.string().trim().min(1).max(2e3);
|
|
6591
|
+
var ColorTokenSchema = z.string().trim().min(1).max(50);
|
|
6592
|
+
var IconNameSchema = OrganizationModelIconTokenSchema;
|
|
6593
|
+
z.string().trim().startsWith("/").max(300);
|
|
6594
|
+
var ReferenceIdsSchema = z.array(ModelIdSchema).default([]);
|
|
6595
|
+
var DisplayMetadataSchema = z.object({
|
|
6596
|
+
label: LabelSchema,
|
|
6597
|
+
description: DescriptionSchema.optional(),
|
|
6598
|
+
color: ColorTokenSchema.optional(),
|
|
6599
|
+
icon: IconNameSchema.optional()
|
|
6600
|
+
});
|
|
6601
|
+
var TechStackEntrySchema = z.object({
|
|
6602
|
+
/** Name of the external platform (e.g. "HubSpot", "Stripe", "Notion"). */
|
|
6603
|
+
platform: z.string().trim().min(1).max(200),
|
|
6604
|
+
/** Free-form description of what this integration is used for. */
|
|
6605
|
+
purpose: z.string().trim().min(1).max(500),
|
|
6606
|
+
/**
|
|
6607
|
+
* Health of the credential backing this integration.
|
|
6608
|
+
* - configured: credential present and valid
|
|
6609
|
+
* - pending: not yet set up
|
|
6610
|
+
* - expired: credential existed but has lapsed
|
|
6611
|
+
* - missing: expected but not present
|
|
6612
|
+
*/
|
|
6613
|
+
credentialStatus: z.enum(["configured", "pending", "expired", "missing"]),
|
|
6614
|
+
/**
|
|
6615
|
+
* Whether this integration is the primary system of record for its domain
|
|
6616
|
+
* (e.g. HubSpot is SoR for contacts). Defaults to false.
|
|
6617
|
+
*/
|
|
6618
|
+
isSystemOfRecord: z.boolean().default(false)
|
|
6619
|
+
});
|
|
6620
|
+
DisplayMetadataSchema.extend({
|
|
6621
|
+
id: ModelIdSchema,
|
|
6622
|
+
resourceId: z.string().trim().min(1).max(255),
|
|
6623
|
+
resourceType: z.enum(["workflow", "agent", "trigger", "integration", "external", "human_checkpoint"]),
|
|
6624
|
+
featureIds: ReferenceIdsSchema,
|
|
6625
|
+
entityIds: ReferenceIdsSchema,
|
|
6626
|
+
surfaceIds: ReferenceIdsSchema,
|
|
6627
|
+
capabilityIds: ReferenceIdsSchema,
|
|
6628
|
+
/** Optional tech-stack metadata for external-SaaS integrations. */
|
|
6629
|
+
techStack: TechStackEntrySchema.optional()
|
|
6630
|
+
});
|
|
6631
|
+
|
|
6632
|
+
// ../core/src/organization-model/domains/sales.ts
|
|
6633
|
+
var SalesStageSemanticClassSchema = z.enum(["open", "active", "nurturing", "closed_won", "closed_lost"]);
|
|
6634
|
+
var SalesStageSchema = DisplayMetadataSchema.extend({
|
|
6635
|
+
id: ModelIdSchema,
|
|
6636
|
+
order: z.number().int().min(0),
|
|
6637
|
+
semanticClass: SalesStageSemanticClassSchema,
|
|
6638
|
+
surfaceIds: ReferenceIdsSchema,
|
|
6639
|
+
resourceIds: ReferenceIdsSchema
|
|
6640
|
+
});
|
|
6641
|
+
var SalesPipelineSchema = z.object({
|
|
6642
|
+
id: ModelIdSchema,
|
|
6643
|
+
label: z.string().trim().min(1).max(120),
|
|
6644
|
+
description: DescriptionSchema.optional(),
|
|
6645
|
+
entityId: ModelIdSchema,
|
|
6646
|
+
stages: z.array(SalesStageSchema).min(1)
|
|
6647
|
+
});
|
|
6648
|
+
z.object({
|
|
6649
|
+
entityId: ModelIdSchema,
|
|
6650
|
+
defaultPipelineId: ModelIdSchema,
|
|
6651
|
+
pipelines: z.array(SalesPipelineSchema).min(1)
|
|
6652
|
+
});
|
|
6653
|
+
var LEAD_GEN_STAGE_CATALOG = {
|
|
6654
|
+
// Prospecting — company population
|
|
6655
|
+
scraped: {
|
|
6656
|
+
key: "scraped",
|
|
6657
|
+
label: "Scraped",
|
|
6658
|
+
description: "Company was scraped from a source directory (Apify actor run).",
|
|
6659
|
+
order: 1,
|
|
6660
|
+
entity: "company"
|
|
6661
|
+
},
|
|
6662
|
+
populated: {
|
|
6663
|
+
key: "populated",
|
|
6664
|
+
label: "Companies found",
|
|
6665
|
+
description: "Companies have been found and added to the lead-gen list.",
|
|
6666
|
+
order: 2,
|
|
6667
|
+
entity: "company"
|
|
6668
|
+
},
|
|
6669
|
+
extracted: {
|
|
6670
|
+
key: "extracted",
|
|
6671
|
+
label: "Websites analyzed",
|
|
6672
|
+
description: "Company websites have been analyzed for business signals.",
|
|
6673
|
+
order: 3,
|
|
6674
|
+
entity: "company"
|
|
6675
|
+
},
|
|
6676
|
+
enriched: {
|
|
6677
|
+
key: "enriched",
|
|
6678
|
+
label: "Enriched",
|
|
6679
|
+
description: "Company or contact enriched with third-party data (e.g. Tomba, Anymailfinder).",
|
|
6680
|
+
order: 4,
|
|
6681
|
+
entity: "company"
|
|
6682
|
+
},
|
|
6683
|
+
"decision-makers-enriched": {
|
|
6684
|
+
key: "decision-makers-enriched",
|
|
6685
|
+
label: "Decision-makers found",
|
|
6686
|
+
description: "Decision-maker contacts discovered and attached to a qualified company.",
|
|
6687
|
+
order: 6,
|
|
6688
|
+
entity: "company"
|
|
6689
|
+
},
|
|
6690
|
+
// Prospecting — contact discovery
|
|
6691
|
+
discovered: {
|
|
6692
|
+
key: "discovered",
|
|
6693
|
+
label: "Decision-makers found",
|
|
6694
|
+
description: "Decision-maker contact details have been found.",
|
|
6695
|
+
order: 5,
|
|
6696
|
+
entity: "contact"
|
|
6697
|
+
},
|
|
6698
|
+
verified: {
|
|
6699
|
+
key: "verified",
|
|
6700
|
+
label: "Emails verified",
|
|
6701
|
+
description: "Contact email addresses have been checked for deliverability.",
|
|
6702
|
+
order: 7,
|
|
6703
|
+
entity: "contact"
|
|
6704
|
+
},
|
|
6705
|
+
// Qualification
|
|
6706
|
+
qualified: {
|
|
6707
|
+
key: "qualified",
|
|
6708
|
+
label: "Companies qualified",
|
|
6709
|
+
description: "Companies have been scored against the qualification criteria.",
|
|
6710
|
+
order: 8,
|
|
6711
|
+
entity: "company"
|
|
6712
|
+
},
|
|
6713
|
+
// Outreach
|
|
6714
|
+
personalized: {
|
|
6715
|
+
key: "personalized",
|
|
6716
|
+
label: "Personalized",
|
|
6717
|
+
description: "Outreach message personalized for the contact (Instantly personalization workflow).",
|
|
6718
|
+
order: 9,
|
|
6719
|
+
entity: "contact"
|
|
6720
|
+
},
|
|
6721
|
+
uploaded: {
|
|
6722
|
+
key: "uploaded",
|
|
6723
|
+
label: "Reviewed and exported",
|
|
6724
|
+
description: "Approved records have been reviewed and exported for handoff.",
|
|
6725
|
+
order: 10,
|
|
6726
|
+
entity: "contact"
|
|
6727
|
+
},
|
|
6728
|
+
interested: {
|
|
6729
|
+
key: "interested",
|
|
6730
|
+
label: "Interested",
|
|
6731
|
+
description: "Contact replied with a positive signal (Instantly reply-handler transition).",
|
|
6732
|
+
order: 11,
|
|
6733
|
+
entity: "contact"
|
|
6734
|
+
}
|
|
6735
|
+
};
|
|
6736
|
+
|
|
6737
|
+
// ../core/src/organization-model/domains/prospecting.ts
|
|
6738
|
+
var ProspectingLifecycleStageSchema = DisplayMetadataSchema.extend({
|
|
6739
|
+
id: ModelIdSchema,
|
|
6740
|
+
order: z.number().int().min(0)
|
|
6741
|
+
});
|
|
6742
|
+
var ProspectingBuildTemplateStepSchema = DisplayMetadataSchema.extend({
|
|
6743
|
+
id: ModelIdSchema,
|
|
6744
|
+
primaryEntity: z.enum(["company", "contact"]),
|
|
6745
|
+
outputs: z.array(z.enum(["company", "contact", "export"])).min(1),
|
|
6746
|
+
stageKey: ModelIdSchema,
|
|
6747
|
+
dependsOn: z.array(ModelIdSchema).optional(),
|
|
6748
|
+
dependencyMode: z.literal("per-record-eligibility"),
|
|
6749
|
+
capabilityKey: ModelIdSchema,
|
|
6750
|
+
defaultBatchSize: z.number().int().positive(),
|
|
6751
|
+
maxBatchSize: z.number().int().positive()
|
|
6752
|
+
}).refine((step) => step.defaultBatchSize <= step.maxBatchSize, {
|
|
6753
|
+
message: "defaultBatchSize must be less than or equal to maxBatchSize",
|
|
6754
|
+
path: ["defaultBatchSize"]
|
|
6755
|
+
});
|
|
6756
|
+
var ProspectingBuildTemplateSchema = DisplayMetadataSchema.extend({
|
|
6757
|
+
id: ModelIdSchema,
|
|
6758
|
+
steps: z.array(ProspectingBuildTemplateStepSchema).min(1)
|
|
6759
|
+
});
|
|
6760
|
+
var CAPABILITY_REGISTRY = {
|
|
6761
|
+
"lead-gen.company.source": "lgn-import-workflow",
|
|
6762
|
+
"lead-gen.company.apollo-import": "lgn-01c-apollo-import-workflow",
|
|
6763
|
+
"lead-gen.contact.discover": "lgn-04-email-discovery-workflow",
|
|
6764
|
+
"lead-gen.contact.verify-email": "lgn-05-email-verification-workflow",
|
|
6765
|
+
"lead-gen.company.website-extract": "lgn-02-website-extract-workflow",
|
|
6766
|
+
"lead-gen.company.qualify": "lgn-03-company-qualification-workflow",
|
|
6767
|
+
"lead-gen.company.dtc-subscription-qualify": "lgn-03b-dtc-subscription-score-workflow",
|
|
6768
|
+
"lead-gen.contact.apollo-decision-maker-enrich": "lgn-04b-apollo-decision-maker-enrich-workflow",
|
|
6769
|
+
"lead-gen.contact.personalize": "ist-personalization-workflow",
|
|
6770
|
+
"lead-gen.review.outreach-ready": "ist-upload-contacts-workflow",
|
|
6771
|
+
"lead-gen.export.list": "lgn-06-export-list-workflow",
|
|
6772
|
+
"lead-gen.company.cleanup": "lgn-company-cleanup-workflow"
|
|
6773
|
+
};
|
|
6774
|
+
var PROSPECTING_STEPS = {
|
|
6775
|
+
localServices: {
|
|
6776
|
+
sourceCompanies: {
|
|
6777
|
+
id: "source-companies",
|
|
6778
|
+
label: "Companies found",
|
|
6779
|
+
primaryEntity: "company",
|
|
6780
|
+
outputs: ["company"],
|
|
6781
|
+
stageKey: "populated",
|
|
6782
|
+
dependencyMode: "per-record-eligibility",
|
|
6783
|
+
capabilityKey: "lead-gen.company.source",
|
|
6784
|
+
defaultBatchSize: 100,
|
|
6785
|
+
maxBatchSize: 250
|
|
6786
|
+
},
|
|
6787
|
+
analyzeWebsites: {
|
|
6788
|
+
id: "analyze-websites",
|
|
6789
|
+
label: "Websites analyzed",
|
|
6790
|
+
primaryEntity: "company",
|
|
6791
|
+
outputs: ["company"],
|
|
6792
|
+
stageKey: "extracted",
|
|
6793
|
+
dependsOn: ["source-companies"],
|
|
6794
|
+
dependencyMode: "per-record-eligibility",
|
|
6795
|
+
capabilityKey: "lead-gen.company.website-extract",
|
|
6796
|
+
defaultBatchSize: 50,
|
|
6797
|
+
maxBatchSize: 100
|
|
6798
|
+
},
|
|
6799
|
+
qualifyCompanies: {
|
|
6800
|
+
id: "qualify-companies",
|
|
6801
|
+
label: "Companies qualified",
|
|
6802
|
+
primaryEntity: "company",
|
|
6803
|
+
outputs: ["company"],
|
|
6804
|
+
stageKey: "qualified",
|
|
6805
|
+
dependsOn: ["analyze-websites"],
|
|
6806
|
+
dependencyMode: "per-record-eligibility",
|
|
6807
|
+
capabilityKey: "lead-gen.company.qualify",
|
|
6808
|
+
defaultBatchSize: 100,
|
|
6809
|
+
maxBatchSize: 250
|
|
6810
|
+
},
|
|
6811
|
+
findContacts: {
|
|
6812
|
+
id: "find-contacts",
|
|
6813
|
+
label: "Decision-makers found",
|
|
6814
|
+
primaryEntity: "contact",
|
|
6815
|
+
outputs: ["contact"],
|
|
6816
|
+
stageKey: "discovered",
|
|
6817
|
+
dependsOn: ["qualify-companies"],
|
|
6818
|
+
dependencyMode: "per-record-eligibility",
|
|
6819
|
+
capabilityKey: "lead-gen.contact.discover",
|
|
6820
|
+
defaultBatchSize: 50,
|
|
6821
|
+
maxBatchSize: 100
|
|
6822
|
+
},
|
|
6823
|
+
verifyEmails: {
|
|
6824
|
+
id: "verify-emails",
|
|
6825
|
+
label: "Emails verified",
|
|
6826
|
+
primaryEntity: "contact",
|
|
6827
|
+
outputs: ["contact"],
|
|
6828
|
+
stageKey: "verified",
|
|
6829
|
+
dependsOn: ["find-contacts"],
|
|
6830
|
+
dependencyMode: "per-record-eligibility",
|
|
6831
|
+
capabilityKey: "lead-gen.contact.verify-email",
|
|
6832
|
+
defaultBatchSize: 100,
|
|
6833
|
+
maxBatchSize: 500
|
|
6834
|
+
},
|
|
6835
|
+
personalize: {
|
|
6836
|
+
id: "personalize",
|
|
6837
|
+
label: "Personalize",
|
|
6838
|
+
primaryEntity: "contact",
|
|
6839
|
+
outputs: ["contact"],
|
|
6840
|
+
stageKey: "personalized",
|
|
6841
|
+
dependsOn: ["verify-emails"],
|
|
6842
|
+
dependencyMode: "per-record-eligibility",
|
|
6843
|
+
capabilityKey: "lead-gen.contact.personalize",
|
|
6844
|
+
defaultBatchSize: 25,
|
|
6845
|
+
maxBatchSize: 100
|
|
6846
|
+
},
|
|
6847
|
+
review: {
|
|
6848
|
+
id: "review",
|
|
6849
|
+
label: "Reviewed and exported",
|
|
6850
|
+
primaryEntity: "contact",
|
|
6851
|
+
outputs: ["export"],
|
|
6852
|
+
stageKey: "uploaded",
|
|
6853
|
+
dependsOn: ["personalize"],
|
|
6854
|
+
dependencyMode: "per-record-eligibility",
|
|
6855
|
+
capabilityKey: "lead-gen.review.outreach-ready",
|
|
6856
|
+
defaultBatchSize: 25,
|
|
6857
|
+
maxBatchSize: 100
|
|
6858
|
+
}
|
|
6859
|
+
},
|
|
6860
|
+
dtcApolloClickup: {
|
|
6861
|
+
importApolloSearch: {
|
|
6862
|
+
id: "import-apollo-search",
|
|
6863
|
+
label: "Companies found",
|
|
6864
|
+
description: "Pull companies and seed contact data from a predefined Apollo search or list.",
|
|
6865
|
+
primaryEntity: "company",
|
|
6866
|
+
outputs: ["company", "contact"],
|
|
6867
|
+
stageKey: "populated",
|
|
6868
|
+
dependencyMode: "per-record-eligibility",
|
|
6869
|
+
capabilityKey: "lead-gen.company.apollo-import",
|
|
6870
|
+
defaultBatchSize: 250,
|
|
6871
|
+
maxBatchSize: 1e3
|
|
6872
|
+
},
|
|
6873
|
+
analyzeWebsites: {
|
|
6874
|
+
id: "analyze-websites",
|
|
6875
|
+
label: "Websites analyzed",
|
|
6876
|
+
description: "Extract subscription, product, retention, and tech-stack signals from each brand website.",
|
|
6877
|
+
primaryEntity: "company",
|
|
6878
|
+
outputs: ["company"],
|
|
6879
|
+
stageKey: "extracted",
|
|
6880
|
+
dependsOn: ["import-apollo-search"],
|
|
6881
|
+
dependencyMode: "per-record-eligibility",
|
|
6882
|
+
capabilityKey: "lead-gen.company.website-extract",
|
|
6883
|
+
defaultBatchSize: 50,
|
|
6884
|
+
maxBatchSize: 100
|
|
6885
|
+
},
|
|
6886
|
+
scoreDtcFit: {
|
|
6887
|
+
id: "score-dtc-fit",
|
|
6888
|
+
label: "Companies qualified",
|
|
6889
|
+
description: "Classify subscription potential, consumable-product fit, retention maturity, and disqualifiers.",
|
|
6890
|
+
primaryEntity: "company",
|
|
6891
|
+
outputs: ["company"],
|
|
6892
|
+
stageKey: "qualified",
|
|
6893
|
+
dependsOn: ["analyze-websites"],
|
|
6894
|
+
dependencyMode: "per-record-eligibility",
|
|
6895
|
+
capabilityKey: "lead-gen.company.dtc-subscription-qualify",
|
|
6896
|
+
defaultBatchSize: 100,
|
|
6897
|
+
maxBatchSize: 250
|
|
6898
|
+
},
|
|
6899
|
+
enrichDecisionMakers: {
|
|
6900
|
+
id: "enrich-decision-makers",
|
|
6901
|
+
label: "Decision-makers found",
|
|
6902
|
+
description: "Use Apollo to find qualified contacts at qualified companies - founders, retention leads, lifecycle leads, and marketing owners.",
|
|
6903
|
+
primaryEntity: "company",
|
|
6904
|
+
outputs: ["contact"],
|
|
6905
|
+
stageKey: "decision-makers-enriched",
|
|
6906
|
+
dependsOn: ["score-dtc-fit"],
|
|
6907
|
+
dependencyMode: "per-record-eligibility",
|
|
6908
|
+
capabilityKey: "lead-gen.contact.apollo-decision-maker-enrich",
|
|
6909
|
+
defaultBatchSize: 100,
|
|
6910
|
+
maxBatchSize: 250
|
|
6911
|
+
},
|
|
6912
|
+
verifyEmails: {
|
|
6913
|
+
id: "verify-emails",
|
|
6914
|
+
label: "Emails verified",
|
|
6915
|
+
description: "Verify deliverability before the QC and handoff step.",
|
|
6916
|
+
primaryEntity: "contact",
|
|
6917
|
+
outputs: ["contact"],
|
|
6918
|
+
stageKey: "verified",
|
|
6919
|
+
dependsOn: ["enrich-decision-makers"],
|
|
6920
|
+
dependencyMode: "per-record-eligibility",
|
|
6921
|
+
capabilityKey: "lead-gen.contact.verify-email",
|
|
6922
|
+
defaultBatchSize: 250,
|
|
6923
|
+
maxBatchSize: 500
|
|
6924
|
+
},
|
|
6925
|
+
reviewAndExport: {
|
|
6926
|
+
id: "review-and-export",
|
|
6927
|
+
label: "Reviewed and exported",
|
|
6928
|
+
description: "Operator QC approves or rejects leads, then approved records are exported as a lead list.",
|
|
6929
|
+
primaryEntity: "company",
|
|
6930
|
+
outputs: ["export"],
|
|
6931
|
+
stageKey: "uploaded",
|
|
6932
|
+
dependsOn: ["verify-emails"],
|
|
6933
|
+
dependencyMode: "per-record-eligibility",
|
|
6934
|
+
capabilityKey: "lead-gen.export.list",
|
|
6935
|
+
defaultBatchSize: 100,
|
|
6936
|
+
maxBatchSize: 250
|
|
6937
|
+
}
|
|
6938
|
+
}
|
|
6939
|
+
};
|
|
6940
|
+
z.object({
|
|
6941
|
+
listEntityId: ModelIdSchema,
|
|
6942
|
+
companyEntityId: ModelIdSchema,
|
|
6943
|
+
contactEntityId: ModelIdSchema,
|
|
6944
|
+
description: DescriptionSchema.optional(),
|
|
6945
|
+
companyStages: z.array(ProspectingLifecycleStageSchema).min(1),
|
|
6946
|
+
contactStages: z.array(ProspectingLifecycleStageSchema).min(1),
|
|
6947
|
+
defaultBuildTemplateId: ModelIdSchema,
|
|
6948
|
+
buildTemplates: z.array(ProspectingBuildTemplateSchema).min(1)
|
|
6949
|
+
});
|
|
6950
|
+
function toProspectingLifecycleStage(stage) {
|
|
6951
|
+
return {
|
|
6952
|
+
id: stage.key,
|
|
6953
|
+
label: stage.label,
|
|
6954
|
+
order: stage.order
|
|
6955
|
+
};
|
|
6956
|
+
}
|
|
6957
|
+
function leadGenStagesForEntity(entity) {
|
|
6958
|
+
return Object.values(LEAD_GEN_STAGE_CATALOG).filter((stage) => stage.entity === entity).sort((a3, b2) => a3.order - b2.order).map(toProspectingLifecycleStage);
|
|
6959
|
+
}
|
|
6960
|
+
var DEFAULT_ORGANIZATION_MODEL_PROSPECTING = {
|
|
6961
|
+
companyStages: leadGenStagesForEntity("company"),
|
|
6962
|
+
contactStages: leadGenStagesForEntity("contact"),
|
|
6963
|
+
buildTemplates: [
|
|
6964
|
+
{
|
|
6965
|
+
id: "local-services",
|
|
6966
|
+
label: "Local Services Prospecting",
|
|
6967
|
+
description: "Curated local-services list build using company sourcing, website analysis, qualification, contact discovery, verification, personalization, and review.",
|
|
6968
|
+
steps: [
|
|
6969
|
+
PROSPECTING_STEPS.localServices.sourceCompanies,
|
|
6970
|
+
PROSPECTING_STEPS.localServices.analyzeWebsites,
|
|
6971
|
+
PROSPECTING_STEPS.localServices.qualifyCompanies,
|
|
6972
|
+
PROSPECTING_STEPS.localServices.findContacts,
|
|
6973
|
+
PROSPECTING_STEPS.localServices.verifyEmails,
|
|
6974
|
+
PROSPECTING_STEPS.localServices.personalize,
|
|
6975
|
+
PROSPECTING_STEPS.localServices.review
|
|
6976
|
+
]
|
|
6977
|
+
},
|
|
6978
|
+
{
|
|
6979
|
+
id: "dtc-subscription-apollo-clickup",
|
|
6980
|
+
label: "DTC Subscription Apollo Export",
|
|
6981
|
+
description: "Prospecting pipeline for DTC subscription or subscription-ready brands where Apollo is the source and contact-enrichment layer, Elevasis handles company research and fit scoring, and approved leads export as an approved lead list.",
|
|
6982
|
+
steps: [
|
|
6983
|
+
PROSPECTING_STEPS.dtcApolloClickup.importApolloSearch,
|
|
6984
|
+
PROSPECTING_STEPS.dtcApolloClickup.analyzeWebsites,
|
|
6985
|
+
PROSPECTING_STEPS.dtcApolloClickup.scoreDtcFit,
|
|
6986
|
+
PROSPECTING_STEPS.dtcApolloClickup.enrichDecisionMakers,
|
|
6987
|
+
PROSPECTING_STEPS.dtcApolloClickup.verifyEmails,
|
|
6988
|
+
PROSPECTING_STEPS.dtcApolloClickup.reviewAndExport
|
|
6989
|
+
]
|
|
6990
|
+
}
|
|
6991
|
+
]
|
|
6992
|
+
};
|
|
6993
|
+
|
|
6994
|
+
// ../core/src/business/acquisition/build-templates.ts
|
|
6995
|
+
var PROSPECTING_BUILD_TEMPLATE_OPTIONS = DEFAULT_ORGANIZATION_MODEL_PROSPECTING.buildTemplates.map(
|
|
6996
|
+
({ id, label, description }) => ({
|
|
6997
|
+
id,
|
|
6998
|
+
label,
|
|
6999
|
+
description
|
|
7000
|
+
})
|
|
7001
|
+
);
|
|
7002
|
+
function isProspectingBuildTemplateId(value) {
|
|
7003
|
+
return PROSPECTING_BUILD_TEMPLATE_OPTIONS.some((template) => template.id === value);
|
|
7004
|
+
}
|
|
7005
|
+
var ProcessingStageStatusSchema = z.enum(["success", "no_result", "skipped", "error"]);
|
|
7006
|
+
var LeadGenStageKeySchema = z.string().refine((value) => Object.prototype.hasOwnProperty.call(LEAD_GEN_STAGE_CATALOG, value), {
|
|
7007
|
+
message: "processing state key must match LEAD_GEN_STAGE_CATALOG"
|
|
7008
|
+
});
|
|
7009
|
+
var LeadGenCapabilityKeySchema = z.string().refine((value) => Object.prototype.hasOwnProperty.call(CAPABILITY_REGISTRY, value), {
|
|
7010
|
+
message: "capabilityKey must match CAPABILITY_REGISTRY"
|
|
7011
|
+
});
|
|
7012
|
+
var ProcessingStateEntrySchema = z.object({
|
|
7013
|
+
status: ProcessingStageStatusSchema,
|
|
7014
|
+
data: z.unknown().optional()
|
|
7015
|
+
}).passthrough();
|
|
7016
|
+
var ProcessingStateSchema = z.record(LeadGenStageKeySchema, ProcessingStateEntrySchema);
|
|
7017
|
+
var CompanyProcessingStateSchema = ProcessingStateSchema;
|
|
7018
|
+
var ContactProcessingStateSchema = ProcessingStateSchema;
|
|
7019
|
+
var DealStageSchema = z.enum(["interested", "proposal", "closing", "closed_won", "closed_lost", "nurturing"]);
|
|
7020
|
+
var AcqDealTaskKindSchema = z.enum(["call", "email", "meeting", "other"]);
|
|
7021
|
+
z.object({
|
|
7022
|
+
dealId: UuidSchema
|
|
7023
|
+
});
|
|
7024
|
+
z.object({
|
|
7025
|
+
dealId: UuidSchema,
|
|
7026
|
+
taskId: UuidSchema
|
|
7027
|
+
});
|
|
7028
|
+
z.object({
|
|
7029
|
+
stage: DealStageSchema.optional(),
|
|
7030
|
+
search: z.string().optional(),
|
|
7031
|
+
limit: z.coerce.number().int().positive().default(50),
|
|
7032
|
+
offset: z.coerce.number().int().min(0).default(0)
|
|
7033
|
+
}).strict();
|
|
7034
|
+
z.object({
|
|
7035
|
+
search: z.string().trim().min(1).max(200).optional(),
|
|
7036
|
+
limit: z.coerce.number().int().min(1).max(25).default(10)
|
|
7037
|
+
}).strict();
|
|
7038
|
+
z.object({
|
|
7039
|
+
window: z.enum(["overdue", "today", "today_and_overdue", "upcoming"]).optional(),
|
|
7040
|
+
assigneeUserId: UuidSchema.optional()
|
|
7041
|
+
}).strict();
|
|
7042
|
+
z.object({
|
|
7043
|
+
body: z.string().trim().min(1).max(1e4)
|
|
7044
|
+
}).strict();
|
|
7045
|
+
z.object({
|
|
7046
|
+
title: z.string().trim().min(1).max(255),
|
|
7047
|
+
description: z.string().nullable().optional(),
|
|
7048
|
+
kind: AcqDealTaskKindSchema.optional(),
|
|
7049
|
+
dueAt: z.string().datetime().nullable().optional(),
|
|
7050
|
+
assigneeUserId: UuidSchema.nullable().optional()
|
|
7051
|
+
}).strict();
|
|
7052
|
+
z.object({
|
|
7053
|
+
pipelineKey: z.string().min(1),
|
|
7054
|
+
stageKey: z.string().min(1),
|
|
7055
|
+
stateKey: z.string().nullable().optional(),
|
|
7056
|
+
reason: z.string().optional(),
|
|
7057
|
+
expectedUpdatedAt: z.string().datetime().optional()
|
|
7058
|
+
}).strict();
|
|
7059
|
+
z.object({
|
|
7060
|
+
stateKey: z.string().min(1),
|
|
7061
|
+
reason: z.string().optional(),
|
|
7062
|
+
expectedUpdatedAt: z.string().datetime().optional()
|
|
7063
|
+
}).strict();
|
|
7064
|
+
z.object({
|
|
7065
|
+
dealId: UuidSchema,
|
|
7066
|
+
actionKey: NonEmptyStringSchema
|
|
7067
|
+
}).strict();
|
|
7068
|
+
z.object({
|
|
7069
|
+
payload: z.record(z.string(), z.unknown()).optional()
|
|
7070
|
+
}).strict();
|
|
7071
|
+
var DealContactSummarySchema = z.object({
|
|
7072
|
+
id: z.string(),
|
|
7073
|
+
first_name: z.string().nullable(),
|
|
7074
|
+
last_name: z.string().nullable(),
|
|
7075
|
+
email: z.string(),
|
|
7076
|
+
title: z.string().nullable(),
|
|
7077
|
+
headline: z.string().nullable(),
|
|
7078
|
+
linkedin_url: z.string().nullable(),
|
|
7079
|
+
processing_state: ProcessingStateSchema.nullable(),
|
|
7080
|
+
enrichment_data: z.record(z.string(), z.unknown()).nullable(),
|
|
7081
|
+
company: z.object({
|
|
7082
|
+
id: z.string(),
|
|
7083
|
+
name: z.string(),
|
|
7084
|
+
domain: z.string().nullable(),
|
|
7085
|
+
website: z.string().nullable(),
|
|
7086
|
+
linkedin_url: z.string().nullable(),
|
|
7087
|
+
segment: z.string().nullable(),
|
|
7088
|
+
category: z.string().nullable(),
|
|
7089
|
+
num_employees: z.number().nullable()
|
|
7090
|
+
}).nullable()
|
|
7091
|
+
});
|
|
7092
|
+
var DealPrioritySchema = z.object({
|
|
7093
|
+
bucketKey: z.enum(["needs_response", "follow_up_due", "waiting", "stale", "closed_low"]),
|
|
7094
|
+
rank: z.number().int(),
|
|
7095
|
+
label: z.string(),
|
|
7096
|
+
color: z.string(),
|
|
7097
|
+
reason: z.string(),
|
|
7098
|
+
latestActivityAt: z.string().nullable(),
|
|
7099
|
+
nextActionAt: z.string().nullable()
|
|
7100
|
+
});
|
|
7101
|
+
var DealListItemSchema = z.object({
|
|
7102
|
+
// acq_deals columns
|
|
7103
|
+
id: z.string(),
|
|
7104
|
+
organization_id: z.string(),
|
|
7105
|
+
contact_id: z.string().nullable(),
|
|
7106
|
+
contact_email: z.string(),
|
|
7107
|
+
pipeline_key: z.string(),
|
|
7108
|
+
stage_key: z.string().nullable(),
|
|
7109
|
+
state_key: z.string().nullable(),
|
|
7110
|
+
activity_log: z.unknown(),
|
|
7111
|
+
discovery_data: z.unknown().nullable(),
|
|
7112
|
+
discovery_submitted_at: z.string().nullable(),
|
|
7113
|
+
discovery_submitted_by: z.string().nullable(),
|
|
7114
|
+
proposal_data: z.unknown().nullable(),
|
|
7115
|
+
proposal_sent_at: z.string().nullable(),
|
|
7116
|
+
proposal_pdf_url: z.string().nullable(),
|
|
7117
|
+
signature_envelope_id: z.string().nullable(),
|
|
7118
|
+
source_list_id: z.string().nullable(),
|
|
7119
|
+
source_type: z.string().nullable(),
|
|
7120
|
+
initial_fee: z.number().nullable(),
|
|
7121
|
+
monthly_fee: z.number().nullable(),
|
|
7122
|
+
closed_lost_at: z.string().nullable(),
|
|
7123
|
+
closed_lost_reason: z.string().nullable(),
|
|
7124
|
+
created_at: z.string(),
|
|
7125
|
+
updated_at: z.string(),
|
|
7126
|
+
priority: DealPrioritySchema,
|
|
7127
|
+
ownership: z.enum(["us", "them"]).nullable(),
|
|
7128
|
+
nextAction: z.string().nullable(),
|
|
7129
|
+
// joined relation
|
|
7130
|
+
contact: DealContactSummarySchema.nullable()
|
|
7131
|
+
});
|
|
7132
|
+
z.object({
|
|
7133
|
+
data: z.array(DealListItemSchema),
|
|
7134
|
+
total: z.number().int(),
|
|
7135
|
+
limit: z.number().int(),
|
|
7136
|
+
offset: z.number().int()
|
|
7137
|
+
});
|
|
7138
|
+
var DealStageSummarySchema = z.object({
|
|
7139
|
+
stage: z.string(),
|
|
7140
|
+
count: z.number().int(),
|
|
7141
|
+
totalValue: z.number(),
|
|
7142
|
+
oldestUpdatedAt: z.string().nullable(),
|
|
7143
|
+
newestUpdatedAt: z.string().nullable()
|
|
7144
|
+
});
|
|
7145
|
+
var StaleDealSummarySchema = z.object({
|
|
7146
|
+
id: z.string(),
|
|
7147
|
+
contactEmail: z.string(),
|
|
7148
|
+
stageKey: z.string(),
|
|
7149
|
+
updatedAt: z.string(),
|
|
7150
|
+
daysStale: z.number().int()
|
|
7151
|
+
});
|
|
7152
|
+
z.object({
|
|
7153
|
+
totalDeals: z.number().int(),
|
|
7154
|
+
openDeals: z.number().int(),
|
|
7155
|
+
wonDeals: z.number().int(),
|
|
7156
|
+
lostDeals: z.number().int(),
|
|
7157
|
+
winRate: z.number(),
|
|
7158
|
+
avgDealSize: z.number(),
|
|
7159
|
+
totalPipelineValue: z.number(),
|
|
7160
|
+
stageSummary: z.array(DealStageSummarySchema),
|
|
7161
|
+
staleDeals: z.array(StaleDealSummarySchema)
|
|
7162
|
+
});
|
|
7163
|
+
var DealLookupItemSchema = z.object({
|
|
7164
|
+
id: z.string(),
|
|
7165
|
+
contactEmail: z.string(),
|
|
7166
|
+
stageKey: z.string().nullable(),
|
|
7167
|
+
updatedAt: z.string(),
|
|
7168
|
+
contactName: z.string().nullable(),
|
|
7169
|
+
companyName: z.string().nullable(),
|
|
7170
|
+
displayLabel: z.string()
|
|
7171
|
+
});
|
|
7172
|
+
z.array(DealLookupItemSchema);
|
|
7173
|
+
var ConversationMessageSchema = z.object({
|
|
7174
|
+
id: z.string(),
|
|
7175
|
+
direction: z.enum(["inbound", "outbound"]),
|
|
7176
|
+
fromEmail: z.string(),
|
|
7177
|
+
toEmail: z.string(),
|
|
7178
|
+
subject: z.string().nullable(),
|
|
7179
|
+
body: z.string(),
|
|
7180
|
+
sentAt: z.string().nullable()
|
|
7181
|
+
});
|
|
7182
|
+
var DealConversationSchema = z.object({
|
|
7183
|
+
messages: z.array(ConversationMessageSchema)
|
|
7184
|
+
});
|
|
7185
|
+
DealListItemSchema.extend({
|
|
7186
|
+
conversation: DealConversationSchema
|
|
7187
|
+
});
|
|
7188
|
+
var DealNoteResponseSchema = z.object({
|
|
7189
|
+
id: z.string(),
|
|
7190
|
+
dealId: z.string(),
|
|
7191
|
+
organizationId: z.string(),
|
|
7192
|
+
authorUserId: z.string().nullable(),
|
|
7193
|
+
body: z.string(),
|
|
7194
|
+
createdAt: z.string(),
|
|
7195
|
+
updatedAt: z.string()
|
|
7196
|
+
});
|
|
7197
|
+
z.array(DealNoteResponseSchema);
|
|
7198
|
+
var DealTaskResponseSchema = z.object({
|
|
7199
|
+
id: z.string(),
|
|
7200
|
+
organizationId: z.string(),
|
|
7201
|
+
dealId: z.string(),
|
|
7202
|
+
title: z.string(),
|
|
7203
|
+
description: z.string().nullable(),
|
|
7204
|
+
kind: AcqDealTaskKindSchema,
|
|
7205
|
+
dueAt: z.string().nullable(),
|
|
7206
|
+
assigneeUserId: z.string().nullable(),
|
|
7207
|
+
completedAt: z.string().nullable(),
|
|
7208
|
+
completedByUserId: z.string().nullable(),
|
|
7209
|
+
createdAt: z.string(),
|
|
7210
|
+
updatedAt: z.string(),
|
|
7211
|
+
createdByUserId: z.string().nullable()
|
|
7212
|
+
});
|
|
7213
|
+
z.array(DealTaskResponseSchema);
|
|
7214
|
+
var ListStatusSchema = z.enum(["draft", "enriching", "launched", "closing", "archived"]);
|
|
7215
|
+
var ScrapingConfigSchema = z.object({
|
|
7216
|
+
vertical: z.string().trim().max(255).optional(),
|
|
7217
|
+
geography: z.string().trim().max(500).optional(),
|
|
7218
|
+
size: z.string().trim().max(255).optional(),
|
|
7219
|
+
apifyInput: z.record(z.string(), z.unknown()).optional()
|
|
7220
|
+
});
|
|
7221
|
+
var IcpRubricSchema = z.object({
|
|
7222
|
+
qualificationRubricKey: z.string().trim().max(255).nullish(),
|
|
7223
|
+
targetDescription: z.string().optional(),
|
|
7224
|
+
minReviewCount: z.number().int().min(0).optional(),
|
|
7225
|
+
minRating: z.number().min(0).max(5).optional(),
|
|
7226
|
+
excludeFranchises: z.boolean().optional(),
|
|
7227
|
+
customRules: z.string().optional()
|
|
7228
|
+
});
|
|
7229
|
+
var PipelineStageSchema = z.object({
|
|
7230
|
+
key: z.string().refine((value) => Object.prototype.hasOwnProperty.call(LEAD_GEN_STAGE_CATALOG, value), {
|
|
7231
|
+
message: "pipeline stage key must match LEAD_GEN_STAGE_CATALOG"
|
|
7232
|
+
}),
|
|
7233
|
+
label: z.string().optional(),
|
|
7234
|
+
enabled: z.boolean().optional(),
|
|
7235
|
+
order: z.number().int().optional()
|
|
7236
|
+
});
|
|
7237
|
+
var PipelineConfigSchema = z.object({
|
|
7238
|
+
stages: z.array(PipelineStageSchema).optional()
|
|
7239
|
+
});
|
|
7240
|
+
var BuildPlanSnapshotStepSchema = z.object({
|
|
7241
|
+
id: z.string().trim().min(1).max(100),
|
|
7242
|
+
label: z.string().trim().min(1).max(120),
|
|
7243
|
+
description: z.string().trim().min(1).max(2e3).optional(),
|
|
7244
|
+
primaryEntity: z.enum(["company", "contact"]),
|
|
7245
|
+
outputs: z.array(z.enum(["company", "contact", "export"])).min(1),
|
|
7246
|
+
stageKey: LeadGenStageKeySchema,
|
|
7247
|
+
dependsOn: z.array(z.string().trim().min(1).max(100)).optional(),
|
|
7248
|
+
dependencyMode: z.literal("per-record-eligibility"),
|
|
7249
|
+
capabilityKey: LeadGenCapabilityKeySchema,
|
|
7250
|
+
defaultBatchSize: z.number().int().positive(),
|
|
7251
|
+
maxBatchSize: z.number().int().positive()
|
|
7252
|
+
}).refine((step) => step.defaultBatchSize <= step.maxBatchSize, {
|
|
7253
|
+
message: "defaultBatchSize must be less than or equal to maxBatchSize",
|
|
7254
|
+
path: ["defaultBatchSize"]
|
|
7255
|
+
});
|
|
7256
|
+
var BuildPlanSnapshotSchema = z.object({
|
|
7257
|
+
templateId: z.string().trim().min(1).max(100),
|
|
7258
|
+
templateLabel: z.string().trim().min(1).max(120),
|
|
7259
|
+
steps: z.array(BuildPlanSnapshotStepSchema).min(1)
|
|
7260
|
+
}).superRefine((snapshot, ctx) => {
|
|
7261
|
+
const stepIds = /* @__PURE__ */ new Set();
|
|
7262
|
+
snapshot.steps.forEach((step, index2) => {
|
|
7263
|
+
if (stepIds.has(step.id)) {
|
|
7264
|
+
ctx.addIssue({
|
|
7265
|
+
code: z.ZodIssueCode.custom,
|
|
7266
|
+
message: `duplicate build-plan step id "${step.id}"`,
|
|
7267
|
+
path: ["steps", index2, "id"]
|
|
7268
|
+
});
|
|
7269
|
+
}
|
|
7270
|
+
stepIds.add(step.id);
|
|
7271
|
+
});
|
|
7272
|
+
snapshot.steps.forEach((step, index2) => {
|
|
7273
|
+
for (const dependencyId of step.dependsOn ?? []) {
|
|
7274
|
+
if (!stepIds.has(dependencyId)) {
|
|
7275
|
+
ctx.addIssue({
|
|
7276
|
+
code: z.ZodIssueCode.custom,
|
|
7277
|
+
message: `dependsOn references unknown build-plan step "${dependencyId}"`,
|
|
7278
|
+
path: ["steps", index2, "dependsOn"]
|
|
7279
|
+
});
|
|
7280
|
+
}
|
|
7281
|
+
}
|
|
7282
|
+
});
|
|
7283
|
+
});
|
|
7284
|
+
var AcqListMetadataSchema = z.object({
|
|
7285
|
+
buildPlanSnapshot: BuildPlanSnapshotSchema.optional()
|
|
7286
|
+
}).catchall(z.unknown());
|
|
7287
|
+
var ProspectingBuildTemplateIdSchema = z.string().trim().min(1).max(100).refine(isProspectingBuildTemplateId, {
|
|
7288
|
+
message: "buildTemplateId must match a known prospecting build template"
|
|
7289
|
+
});
|
|
7290
|
+
var ListStageCountsSchema = z.object({
|
|
7291
|
+
// Attempted counts by canonical lead-gen stage. The detailed status
|
|
7292
|
+
// distribution lives on ListProgress; telemetry keeps the overview payload small.
|
|
7293
|
+
stageCounts: z.object({
|
|
7294
|
+
populated: z.number().int(),
|
|
7295
|
+
extracted: z.number().int(),
|
|
7296
|
+
qualified: z.number().int(),
|
|
7297
|
+
discovered: z.number().int(),
|
|
7298
|
+
verified: z.number().int(),
|
|
7299
|
+
personalized: z.number().int(),
|
|
7300
|
+
uploaded: z.number().int()
|
|
7301
|
+
}),
|
|
7302
|
+
deliverability: z.object({
|
|
7303
|
+
valid: z.number().int(),
|
|
7304
|
+
risky: z.number().int(),
|
|
7305
|
+
invalid: z.number().int(),
|
|
7306
|
+
unknown: z.number().int(),
|
|
7307
|
+
bounced: z.number().int()
|
|
7308
|
+
})
|
|
7309
|
+
});
|
|
7310
|
+
var ListTelemetrySchema = z.object({
|
|
7311
|
+
listId: UuidSchema,
|
|
7312
|
+
totalCompanies: z.number().int(),
|
|
7313
|
+
totalContacts: z.number().int(),
|
|
7314
|
+
stageCounts: ListStageCountsSchema.shape.stageCounts,
|
|
7315
|
+
deliverability: ListStageCountsSchema.shape.deliverability,
|
|
7316
|
+
activeWorkflows: z.array(z.string()).optional()
|
|
7317
|
+
});
|
|
7318
|
+
z.object({
|
|
7319
|
+
listId: UuidSchema
|
|
7320
|
+
});
|
|
7321
|
+
z.object({
|
|
7322
|
+
name: z.string().trim().min(1).max(255),
|
|
7323
|
+
description: z.string().trim().nullable().optional(),
|
|
7324
|
+
status: ListStatusSchema.optional(),
|
|
7325
|
+
buildTemplateId: ProspectingBuildTemplateIdSchema.optional(),
|
|
7326
|
+
scrapingConfig: ScrapingConfigSchema.optional(),
|
|
7327
|
+
icp: IcpRubricSchema.optional(),
|
|
7328
|
+
pipelineConfig: PipelineConfigSchema.optional()
|
|
7329
|
+
}).strict();
|
|
7330
|
+
z.object({
|
|
7331
|
+
name: z.string().trim().min(1).max(255).optional(),
|
|
7332
|
+
description: z.string().trim().nullable().optional(),
|
|
7333
|
+
batchIds: z.array(z.string()).optional(),
|
|
7334
|
+
buildTemplateId: ProspectingBuildTemplateIdSchema.optional(),
|
|
7335
|
+
confirmBuildTemplateChange: z.literal(true).optional()
|
|
7336
|
+
}).strict().refine(
|
|
7337
|
+
(data) => data.name !== void 0 || data.description !== void 0 || data.batchIds !== void 0 || data.buildTemplateId !== void 0,
|
|
7338
|
+
{
|
|
7339
|
+
message: "At least one field (name, description, batchIds, or buildTemplateId) must be provided"
|
|
7340
|
+
}
|
|
7341
|
+
).refine((data) => data.buildTemplateId === void 0 || data.confirmBuildTemplateChange === true, {
|
|
7342
|
+
message: "confirmBuildTemplateChange must be true when changing buildTemplateId",
|
|
7343
|
+
path: ["confirmBuildTemplateChange"]
|
|
7344
|
+
});
|
|
7345
|
+
z.object({
|
|
7346
|
+
status: ListStatusSchema
|
|
7347
|
+
}).strict();
|
|
7348
|
+
z.object({
|
|
7349
|
+
scrapingConfig: ScrapingConfigSchema.partial().optional(),
|
|
7350
|
+
icp: IcpRubricSchema.partial().optional(),
|
|
7351
|
+
pipelineConfig: PipelineConfigSchema.partial().optional()
|
|
7352
|
+
}).strict().refine((data) => data.scrapingConfig !== void 0 || data.icp !== void 0 || data.pipelineConfig !== void 0, {
|
|
7353
|
+
message: "At least one of scrapingConfig, icp, or pipelineConfig must be provided"
|
|
7354
|
+
});
|
|
7355
|
+
z.object({
|
|
7356
|
+
companyIds: z.array(UuidSchema).min(1).max(1e3)
|
|
7357
|
+
}).strict();
|
|
7358
|
+
z.object({
|
|
7359
|
+
companyIds: z.array(UuidSchema).min(1).max(1e3)
|
|
7360
|
+
}).strict();
|
|
7361
|
+
z.object({
|
|
7362
|
+
contactIds: z.array(UuidSchema).min(1).max(1e3)
|
|
7363
|
+
}).strict();
|
|
7364
|
+
z.object({
|
|
7365
|
+
executionId: UuidSchema,
|
|
7366
|
+
configSnapshot: z.record(z.string(), z.unknown()).optional()
|
|
7367
|
+
}).strict();
|
|
7368
|
+
var AcqListResponseSchema = z.object({
|
|
7369
|
+
id: z.string(),
|
|
7370
|
+
organizationId: z.string(),
|
|
7371
|
+
name: z.string(),
|
|
7372
|
+
description: z.string().nullable(),
|
|
7373
|
+
batchIds: z.array(z.string()),
|
|
7374
|
+
instantlyCampaignId: z.string().nullable(),
|
|
7375
|
+
/** Lifecycle status (draft | enriching | launched | closing | archived). */
|
|
7376
|
+
status: ListStatusSchema,
|
|
7377
|
+
metadata: AcqListMetadataSchema,
|
|
7378
|
+
launchedAt: z.string().nullable(),
|
|
7379
|
+
completedAt: z.string().nullable(),
|
|
7380
|
+
createdAt: z.string(),
|
|
7381
|
+
/** Scraping criteria stored as jsonb on the row. */
|
|
7382
|
+
scrapingConfig: ScrapingConfigSchema,
|
|
7383
|
+
/** ICP / qualification rubric stored as jsonb on the row. */
|
|
7384
|
+
icp: IcpRubricSchema,
|
|
7385
|
+
/** Pipeline presentation contract stored as jsonb on the row. */
|
|
7386
|
+
pipelineConfig: PipelineConfigSchema
|
|
7387
|
+
});
|
|
7388
|
+
z.array(AcqListResponseSchema);
|
|
7389
|
+
z.array(ListTelemetrySchema);
|
|
7390
|
+
var ListStageProgressSchema = z.object({
|
|
7391
|
+
total: z.number().int().min(0),
|
|
7392
|
+
attempted: z.number().int().min(0),
|
|
7393
|
+
success: z.number().int().min(0),
|
|
7394
|
+
noResult: z.number().int().min(0),
|
|
7395
|
+
skipped: z.number().int().min(0),
|
|
7396
|
+
error: z.number().int().min(0),
|
|
7397
|
+
other: z.number().int().min(0),
|
|
7398
|
+
notAttempted: z.number().int().min(0)
|
|
7399
|
+
});
|
|
7400
|
+
z.object({
|
|
7401
|
+
totalMembers: z.number().int().min(0),
|
|
7402
|
+
totalCompanies: z.number().int().min(0),
|
|
7403
|
+
byCompanyStage: z.record(z.string(), ListStageProgressSchema),
|
|
7404
|
+
byContactStage: z.record(z.string(), ListStageProgressSchema)
|
|
7405
|
+
});
|
|
7406
|
+
var ListExecutionSummarySchema = z.object({
|
|
7407
|
+
executionId: z.string(),
|
|
7408
|
+
resourceId: z.string(),
|
|
7409
|
+
status: z.string(),
|
|
7410
|
+
createdAt: z.string(),
|
|
7411
|
+
completedAt: z.string().nullable(),
|
|
7412
|
+
durationMs: z.number().int().nullable(),
|
|
7413
|
+
input: z.unknown().nullable().optional()
|
|
7414
|
+
});
|
|
7415
|
+
z.array(ListExecutionSummarySchema);
|
|
7416
|
+
var QueryBooleanSchema = z.preprocess((value) => {
|
|
7417
|
+
if (value === "true" || value === "1" || value === true) return true;
|
|
7418
|
+
if (value === "false" || value === "0" || value === false) return false;
|
|
7419
|
+
return value;
|
|
7420
|
+
}, z.boolean());
|
|
7421
|
+
var AcqCompanyStatusSchema = z.enum(["active", "invalid"]);
|
|
7422
|
+
var AcqContactStatusSchema = z.enum(["active", "invalid"]);
|
|
7423
|
+
var AcqEmailValidSchema = z.enum(["VALID", "INVALID", "RISKY", "UNKNOWN"]);
|
|
7424
|
+
z.object({
|
|
7425
|
+
companyId: UuidSchema
|
|
7426
|
+
});
|
|
7427
|
+
z.object({
|
|
7428
|
+
contactId: UuidSchema
|
|
7429
|
+
});
|
|
7430
|
+
z.object({
|
|
7431
|
+
search: z.string().trim().min(1).max(200).optional(),
|
|
7432
|
+
listId: UuidSchema.optional(),
|
|
7433
|
+
domain: z.string().trim().min(1).max(255).optional(),
|
|
7434
|
+
website: z.string().trim().min(1).max(2048).optional(),
|
|
7435
|
+
segment: z.string().trim().min(1).max(255).optional(),
|
|
7436
|
+
category: z.string().trim().min(1).max(255).optional(),
|
|
7437
|
+
pipelineStatus: z.unknown().optional(),
|
|
7438
|
+
batchId: z.string().trim().min(1).max(255).optional(),
|
|
7439
|
+
status: AcqCompanyStatusSchema.optional(),
|
|
7440
|
+
includeAll: QueryBooleanSchema.optional(),
|
|
7441
|
+
limit: z.coerce.number().int().min(1).max(5e3).default(50),
|
|
7442
|
+
offset: z.coerce.number().int().min(0).default(0)
|
|
7443
|
+
}).strict();
|
|
7444
|
+
z.object({
|
|
7445
|
+
search: z.string().trim().min(1).max(200).optional(),
|
|
7446
|
+
listId: UuidSchema.optional(),
|
|
7447
|
+
openingLineIsNull: QueryBooleanSchema.optional(),
|
|
7448
|
+
batchId: z.string().trim().min(1).max(255).optional(),
|
|
7449
|
+
contactStatus: AcqContactStatusSchema.optional(),
|
|
7450
|
+
limit: z.coerce.number().int().min(1).max(5e3).default(5e3),
|
|
7451
|
+
offset: z.coerce.number().int().min(0).default(0)
|
|
7452
|
+
}).strict();
|
|
7453
|
+
z.object({
|
|
7454
|
+
name: z.string().trim().min(1).max(255),
|
|
7455
|
+
domain: z.string().trim().min(1).max(255).optional(),
|
|
7456
|
+
linkedinUrl: z.string().trim().url().optional(),
|
|
7457
|
+
website: z.string().trim().url().optional(),
|
|
7458
|
+
numEmployees: z.number().int().min(0).optional(),
|
|
7459
|
+
foundedYear: z.number().int().optional(),
|
|
7460
|
+
locationCity: z.string().trim().min(1).max(255).optional(),
|
|
7461
|
+
locationState: z.string().trim().min(1).max(255).optional(),
|
|
7462
|
+
category: z.string().trim().min(1).max(255).optional(),
|
|
7463
|
+
source: z.string().trim().min(1).max(255).optional(),
|
|
7464
|
+
batchId: z.string().trim().min(1).max(255).optional(),
|
|
7465
|
+
pipelineStatus: z.unknown().optional(),
|
|
7466
|
+
verticalResearch: z.string().trim().min(1).max(5e3).optional()
|
|
7467
|
+
}).strict();
|
|
7468
|
+
z.object({
|
|
7469
|
+
name: z.string().trim().min(1).max(255).optional(),
|
|
7470
|
+
domain: z.string().trim().min(1).max(255).optional(),
|
|
7471
|
+
linkedinUrl: z.string().trim().url().optional(),
|
|
7472
|
+
website: z.string().trim().url().optional(),
|
|
7473
|
+
numEmployees: z.number().int().min(0).optional(),
|
|
7474
|
+
foundedYear: z.number().int().optional(),
|
|
7475
|
+
locationCity: z.string().trim().min(1).max(255).optional(),
|
|
7476
|
+
locationState: z.string().trim().min(1).max(255).optional(),
|
|
7477
|
+
category: z.string().trim().min(1).max(255).optional(),
|
|
7478
|
+
segment: z.string().trim().min(1).max(255).optional(),
|
|
7479
|
+
processingState: CompanyProcessingStateSchema.optional(),
|
|
7480
|
+
pipelineStatus: z.unknown().optional(),
|
|
7481
|
+
enrichmentData: z.record(z.string(), z.unknown()).optional(),
|
|
7482
|
+
source: z.string().trim().min(1).max(255).optional(),
|
|
7483
|
+
batchId: z.string().trim().min(1).max(255).optional(),
|
|
7484
|
+
status: AcqCompanyStatusSchema.optional(),
|
|
7485
|
+
verticalResearch: z.string().trim().min(1).max(5e3).nullable().optional()
|
|
7486
|
+
}).strict().refine(
|
|
7487
|
+
(data) => data.name !== void 0 || data.domain !== void 0 || data.linkedinUrl !== void 0 || data.website !== void 0 || data.numEmployees !== void 0 || data.foundedYear !== void 0 || data.locationCity !== void 0 || data.locationState !== void 0 || data.category !== void 0 || data.segment !== void 0 || data.processingState !== void 0 || data.pipelineStatus !== void 0 || data.enrichmentData !== void 0 || data.source !== void 0 || data.batchId !== void 0 || data.status !== void 0 || data.verticalResearch !== void 0,
|
|
7488
|
+
{
|
|
7489
|
+
message: "At least one field must be provided"
|
|
7490
|
+
}
|
|
7491
|
+
);
|
|
7492
|
+
z.object({
|
|
7493
|
+
email: z.string().trim().email(),
|
|
7494
|
+
companyId: UuidSchema.optional(),
|
|
7495
|
+
firstName: z.string().trim().min(1).max(255).optional(),
|
|
7496
|
+
lastName: z.string().trim().min(1).max(255).optional(),
|
|
7497
|
+
linkedinUrl: z.string().trim().url().optional(),
|
|
7498
|
+
title: z.string().trim().min(1).max(255).optional(),
|
|
7499
|
+
source: z.string().trim().min(1).max(255).optional(),
|
|
7500
|
+
sourceId: z.string().trim().min(1).max(255).optional(),
|
|
7501
|
+
batchId: z.string().trim().min(1).max(255).optional(),
|
|
7502
|
+
pipelineStatus: z.unknown().optional()
|
|
7503
|
+
}).strict();
|
|
7504
|
+
z.object({
|
|
7505
|
+
companyId: UuidSchema.optional(),
|
|
7506
|
+
emailValid: AcqEmailValidSchema.optional(),
|
|
7507
|
+
firstName: z.string().trim().min(1).max(255).optional(),
|
|
7508
|
+
lastName: z.string().trim().min(1).max(255).optional(),
|
|
7509
|
+
linkedinUrl: z.string().trim().url().optional(),
|
|
7510
|
+
title: z.string().trim().min(1).max(255).optional(),
|
|
7511
|
+
headline: z.string().trim().min(1).max(5e3).optional(),
|
|
7512
|
+
filterReason: z.string().trim().min(1).max(5e3).optional(),
|
|
7513
|
+
openingLine: z.string().trim().min(1).max(5e3).optional(),
|
|
7514
|
+
processingState: ContactProcessingStateSchema.optional(),
|
|
7515
|
+
pipelineStatus: z.unknown().optional(),
|
|
7516
|
+
enrichmentData: z.record(z.string(), z.unknown()).optional(),
|
|
7517
|
+
status: AcqContactStatusSchema.optional()
|
|
7518
|
+
}).strict().refine(
|
|
7519
|
+
(data) => data.companyId !== void 0 || data.emailValid !== void 0 || data.firstName !== void 0 || data.lastName !== void 0 || data.linkedinUrl !== void 0 || data.title !== void 0 || data.headline !== void 0 || data.filterReason !== void 0 || data.openingLine !== void 0 || data.processingState !== void 0 || data.pipelineStatus !== void 0 || data.enrichmentData !== void 0 || data.status !== void 0,
|
|
7520
|
+
{
|
|
7521
|
+
message: "At least one field must be provided"
|
|
7522
|
+
}
|
|
7523
|
+
);
|
|
7524
|
+
var AcqCompanyResponseSchema = z.object({
|
|
7525
|
+
id: z.string(),
|
|
7526
|
+
organizationId: z.string(),
|
|
7527
|
+
name: z.string(),
|
|
7528
|
+
domain: z.string().nullable(),
|
|
7529
|
+
linkedinUrl: z.string().nullable(),
|
|
7530
|
+
website: z.string().nullable(),
|
|
7531
|
+
numEmployees: z.number().nullable(),
|
|
7532
|
+
foundedYear: z.number().nullable(),
|
|
7533
|
+
locationCity: z.string().nullable(),
|
|
7534
|
+
locationState: z.string().nullable(),
|
|
7535
|
+
category: z.string().nullable(),
|
|
7536
|
+
categoryPain: z.string().nullable(),
|
|
7537
|
+
segment: z.string().nullable(),
|
|
7538
|
+
processingState: CompanyProcessingStateSchema.nullable(),
|
|
7539
|
+
pipelineStatus: z.unknown().nullable().optional(),
|
|
7540
|
+
enrichmentData: z.record(z.string(), z.unknown()).nullable(),
|
|
7541
|
+
source: z.string().nullable(),
|
|
7542
|
+
batchId: z.string().nullable(),
|
|
7543
|
+
status: AcqCompanyStatusSchema,
|
|
7544
|
+
contactCount: z.number().int().min(0),
|
|
7545
|
+
verticalResearch: z.string().nullable(),
|
|
7546
|
+
createdAt: z.string(),
|
|
7547
|
+
updatedAt: z.string()
|
|
7548
|
+
});
|
|
7549
|
+
z.object({
|
|
7550
|
+
data: z.array(AcqCompanyResponseSchema),
|
|
7551
|
+
total: z.number().int(),
|
|
7552
|
+
limit: z.number().int(),
|
|
7553
|
+
offset: z.number().int()
|
|
7554
|
+
});
|
|
7555
|
+
z.object({
|
|
7556
|
+
segments: z.array(z.string()),
|
|
7557
|
+
categories: z.array(z.string()),
|
|
7558
|
+
statuses: z.array(AcqCompanyStatusSchema)
|
|
7559
|
+
});
|
|
7560
|
+
var AcqContactCompanySummarySchema = z.object({
|
|
7561
|
+
id: z.string(),
|
|
7562
|
+
name: z.string(),
|
|
7563
|
+
domain: z.string().nullable(),
|
|
7564
|
+
website: z.string().nullable(),
|
|
7565
|
+
linkedinUrl: z.string().nullable(),
|
|
7566
|
+
segment: z.string().nullable(),
|
|
7567
|
+
category: z.string().nullable(),
|
|
7568
|
+
status: AcqCompanyStatusSchema
|
|
7569
|
+
});
|
|
7570
|
+
var AcqContactResponseSchema = z.object({
|
|
7571
|
+
id: z.string(),
|
|
7572
|
+
organizationId: z.string(),
|
|
7573
|
+
companyId: z.string().nullable(),
|
|
7574
|
+
email: z.string(),
|
|
7575
|
+
emailValid: AcqEmailValidSchema.nullable(),
|
|
7576
|
+
firstName: z.string().nullable(),
|
|
7577
|
+
lastName: z.string().nullable(),
|
|
7578
|
+
linkedinUrl: z.string().nullable(),
|
|
7579
|
+
title: z.string().nullable(),
|
|
7580
|
+
headline: z.string().nullable(),
|
|
7581
|
+
filterReason: z.string().nullable(),
|
|
7582
|
+
openingLine: z.string().nullable(),
|
|
7583
|
+
source: z.string().nullable(),
|
|
7584
|
+
sourceId: z.string().nullable(),
|
|
7585
|
+
processingState: ContactProcessingStateSchema.nullable(),
|
|
7586
|
+
pipelineStatus: z.unknown().nullable().optional(),
|
|
7587
|
+
enrichmentData: z.record(z.string(), z.unknown()).nullable(),
|
|
7588
|
+
attioPersonId: z.string().nullable(),
|
|
7589
|
+
batchId: z.string().nullable(),
|
|
7590
|
+
status: AcqContactStatusSchema,
|
|
7591
|
+
company: AcqContactCompanySummarySchema.nullable().optional(),
|
|
7592
|
+
createdAt: z.string(),
|
|
7593
|
+
updatedAt: z.string()
|
|
7594
|
+
});
|
|
7595
|
+
z.object({
|
|
7596
|
+
data: z.array(AcqContactResponseSchema),
|
|
7597
|
+
total: z.number().int(),
|
|
7598
|
+
limit: z.number().int(),
|
|
7599
|
+
offset: z.number().int()
|
|
7600
|
+
});
|
|
7601
|
+
var AcqArtifactOwnerKindSchema = z.enum(["company", "contact", "deal", "list", "list_member"]);
|
|
7602
|
+
z.object({
|
|
7603
|
+
ownerKind: AcqArtifactOwnerKindSchema,
|
|
7604
|
+
ownerId: UuidSchema
|
|
7605
|
+
}).strict();
|
|
7606
|
+
z.object({
|
|
7607
|
+
ownerKind: AcqArtifactOwnerKindSchema,
|
|
7608
|
+
ownerId: UuidSchema,
|
|
7609
|
+
kind: z.string().trim().min(1).max(255),
|
|
7610
|
+
content: z.record(z.string(), z.unknown()),
|
|
7611
|
+
sourceExecutionId: UuidSchema.optional()
|
|
7612
|
+
}).strict();
|
|
7613
|
+
var AcqArtifactResponseSchema = z.object({
|
|
7614
|
+
id: z.string(),
|
|
7615
|
+
organizationId: z.string(),
|
|
7616
|
+
ownerKind: z.string(),
|
|
7617
|
+
ownerId: z.string(),
|
|
7618
|
+
kind: z.string(),
|
|
7619
|
+
content: z.record(z.string(), z.unknown()),
|
|
7620
|
+
sourceExecutionId: z.string().nullable(),
|
|
7621
|
+
createdBy: z.string().nullable(),
|
|
7622
|
+
createdAt: z.string(),
|
|
7623
|
+
version: z.number().int()
|
|
7624
|
+
});
|
|
7625
|
+
z.object({
|
|
7626
|
+
artifacts: z.array(AcqArtifactResponseSchema)
|
|
7627
|
+
});
|
|
7628
|
+
z.object({
|
|
7629
|
+
limit: z.coerce.number().int().min(1).max(500).default(50),
|
|
7630
|
+
offset: z.coerce.number().int().min(0).default(0)
|
|
7631
|
+
}).strict();
|
|
7632
|
+
z.object({
|
|
7633
|
+
memberId: UuidSchema
|
|
7634
|
+
});
|
|
7635
|
+
var AcqListMemberContactSummarySchema = z.object({
|
|
7636
|
+
id: z.string(),
|
|
7637
|
+
email: z.string(),
|
|
7638
|
+
firstName: z.string().nullable(),
|
|
7639
|
+
lastName: z.string().nullable(),
|
|
7640
|
+
title: z.string().nullable(),
|
|
7641
|
+
linkedinUrl: z.string().nullable(),
|
|
7642
|
+
companyId: z.string().nullable()
|
|
7643
|
+
});
|
|
7644
|
+
var AcqListMemberResponseSchema = z.object({
|
|
7645
|
+
id: z.string(),
|
|
7646
|
+
listId: z.string(),
|
|
7647
|
+
contactId: z.string(),
|
|
7648
|
+
pipelineKey: z.string(),
|
|
7649
|
+
stageKey: z.string(),
|
|
7650
|
+
stateKey: z.string(),
|
|
7651
|
+
activityLog: z.unknown(),
|
|
7652
|
+
addedAt: z.string(),
|
|
7653
|
+
addedBy: z.string().nullable(),
|
|
7654
|
+
sourceExecutionId: z.string().nullable(),
|
|
7655
|
+
contact: AcqListMemberContactSummarySchema.nullable()
|
|
7656
|
+
});
|
|
7657
|
+
z.object({
|
|
7658
|
+
members: z.array(AcqListMemberResponseSchema)
|
|
7659
|
+
});
|
|
7660
|
+
z.object({
|
|
7661
|
+
listCompanyId: UuidSchema
|
|
7662
|
+
});
|
|
7663
|
+
z.object({
|
|
7664
|
+
id: z.string(),
|
|
7665
|
+
listId: z.string(),
|
|
7666
|
+
companyId: z.string(),
|
|
7667
|
+
pipelineKey: z.string(),
|
|
7668
|
+
stageKey: z.string(),
|
|
7669
|
+
stateKey: z.string(),
|
|
7670
|
+
activityLog: z.unknown(),
|
|
7671
|
+
addedAt: z.string(),
|
|
7672
|
+
addedBy: z.string().nullable(),
|
|
7673
|
+
sourceExecutionId: z.string().nullable()
|
|
7674
|
+
});
|
|
6491
7675
|
var RETRYABLE_CODES = /* @__PURE__ */ new Set([
|
|
6492
7676
|
"rate_limit_exceeded",
|
|
6493
7677
|
"network_error",
|
|
@@ -6821,7 +8005,9 @@ createAdapter("list", [
|
|
|
6821
8005
|
"getConfig",
|
|
6822
8006
|
"recordExecution",
|
|
6823
8007
|
"updateCompanyStage",
|
|
6824
|
-
"updateContactStage"
|
|
8008
|
+
"updateContactStage",
|
|
8009
|
+
"listPendingCompanyIds",
|
|
8010
|
+
"listPendingContactIds"
|
|
6825
8011
|
]);
|
|
6826
8012
|
|
|
6827
8013
|
// src/worker/adapters/pdf.ts
|
|
@@ -6836,728 +8022,740 @@ createAdapter("execution", ["trigger", "triggerAsync"]);
|
|
|
6836
8022
|
// src/worker/adapters/email.ts
|
|
6837
8023
|
createAdapter("email", ["send"]);
|
|
6838
8024
|
|
|
6839
|
-
// src/
|
|
6840
|
-
|
|
6841
|
-
|
|
6842
|
-
|
|
6843
|
-
|
|
6844
|
-
|
|
6845
|
-
|
|
6846
|
-
|
|
6847
|
-
logs.push(entry);
|
|
6848
|
-
parentPort?.postMessage({
|
|
6849
|
-
type: "log",
|
|
6850
|
-
entry: { level, message, timestamp, executionId, context: logContext }
|
|
6851
|
-
});
|
|
6852
|
-
};
|
|
6853
|
-
const capture = (level, orig) => (...args) => {
|
|
6854
|
-
postLog(level, args.map(String).join(" "));
|
|
6855
|
-
orig(...args);
|
|
6856
|
-
};
|
|
6857
|
-
console.log = capture("info", origLog);
|
|
6858
|
-
console.warn = capture("warn", origWarn);
|
|
6859
|
-
console.error = capture("error", origError);
|
|
6860
|
-
return {
|
|
6861
|
-
restore: () => {
|
|
6862
|
-
console.log = origLog;
|
|
6863
|
-
console.warn = origWarn;
|
|
6864
|
-
console.error = origError;
|
|
6865
|
-
},
|
|
6866
|
-
postLog
|
|
6867
|
-
};
|
|
6868
|
-
}
|
|
6869
|
-
var LOG_STRING_TRUNCATE_LIMIT = 200;
|
|
6870
|
-
function truncateForLogging(value) {
|
|
6871
|
-
if (value === null || value === void 0) return value;
|
|
6872
|
-
if (typeof value === "string") {
|
|
6873
|
-
return value.length > LOG_STRING_TRUNCATE_LIMIT ? value.slice(0, LOG_STRING_TRUNCATE_LIMIT) + `\u2026 [${value.length} chars]` : value;
|
|
6874
|
-
}
|
|
6875
|
-
if (Array.isArray(value)) {
|
|
6876
|
-
return value.map(truncateForLogging);
|
|
8025
|
+
// ../core/src/platform/registry/validation.ts
|
|
8026
|
+
var RegistryValidationError = class extends Error {
|
|
8027
|
+
constructor(orgName, resourceId, field, message) {
|
|
8028
|
+
super(message);
|
|
8029
|
+
this.orgName = orgName;
|
|
8030
|
+
this.resourceId = resourceId;
|
|
8031
|
+
this.field = field;
|
|
8032
|
+
this.name = "RegistryValidationError";
|
|
6877
8033
|
}
|
|
6878
|
-
|
|
6879
|
-
|
|
6880
|
-
|
|
6881
|
-
|
|
8034
|
+
};
|
|
8035
|
+
function validateDeploymentSpec(orgName, resources) {
|
|
8036
|
+
const seenIds = /* @__PURE__ */ new Set();
|
|
8037
|
+
resources.workflows?.forEach((workflow) => {
|
|
8038
|
+
const id = workflow.config.resourceId;
|
|
8039
|
+
if (seenIds.has(id)) {
|
|
8040
|
+
throw new RegistryValidationError(
|
|
8041
|
+
orgName,
|
|
8042
|
+
id,
|
|
8043
|
+
null,
|
|
8044
|
+
`Duplicate resourceId "${id}" in organization "${orgName}". Workflows and agents must have unique IDs within an organization.`
|
|
8045
|
+
);
|
|
6882
8046
|
}
|
|
6883
|
-
|
|
6884
|
-
|
|
6885
|
-
|
|
8047
|
+
seenIds.add(id);
|
|
8048
|
+
if ("modelConfig" in workflow && workflow.modelConfig) {
|
|
8049
|
+
validateResourceModelConfig(orgName, id, workflow.modelConfig);
|
|
8050
|
+
}
|
|
8051
|
+
if (workflow.interface) {
|
|
8052
|
+
validateExecutionInterface(orgName, id, workflow.interface, workflow.contract.inputSchema);
|
|
8053
|
+
}
|
|
8054
|
+
});
|
|
8055
|
+
resources.agents?.forEach((agent) => {
|
|
8056
|
+
const id = agent.config.resourceId;
|
|
8057
|
+
if (seenIds.has(id)) {
|
|
8058
|
+
throw new RegistryValidationError(
|
|
8059
|
+
orgName,
|
|
8060
|
+
id,
|
|
8061
|
+
null,
|
|
8062
|
+
`Duplicate resourceId "${id}" in organization "${orgName}". Workflows and agents must have unique IDs within an organization.`
|
|
8063
|
+
);
|
|
8064
|
+
}
|
|
8065
|
+
seenIds.add(id);
|
|
8066
|
+
validateResourceModelConfig(orgName, id, agent.modelConfig);
|
|
8067
|
+
if (agent.interface) {
|
|
8068
|
+
validateExecutionInterface(orgName, id, agent.interface, agent.contract.inputSchema);
|
|
8069
|
+
}
|
|
8070
|
+
});
|
|
6886
8071
|
}
|
|
6887
|
-
function
|
|
6888
|
-
|
|
6889
|
-
|
|
6890
|
-
|
|
6891
|
-
if (
|
|
8072
|
+
function validateResourceModelConfig(orgName, resourceId, modelConfig) {
|
|
8073
|
+
try {
|
|
8074
|
+
validateModelConfig(modelConfig);
|
|
8075
|
+
} catch (error) {
|
|
8076
|
+
if (error instanceof ModelConfigError) {
|
|
8077
|
+
throw new RegistryValidationError(
|
|
8078
|
+
orgName,
|
|
8079
|
+
resourceId,
|
|
8080
|
+
error.field,
|
|
8081
|
+
`Invalid model config in ${orgName}/${resourceId}: ${error.message} (field: ${error.field})`
|
|
8082
|
+
);
|
|
8083
|
+
}
|
|
8084
|
+
throw error;
|
|
6892
8085
|
}
|
|
6893
|
-
return next.default;
|
|
6894
8086
|
}
|
|
6895
|
-
function
|
|
6896
|
-
|
|
6897
|
-
|
|
6898
|
-
|
|
6899
|
-
|
|
6900
|
-
|
|
6901
|
-
}
|
|
6902
|
-
} catch {
|
|
8087
|
+
function validateExecutionInterface(orgName, resourceId, executionInterface, inputSchema) {
|
|
8088
|
+
const form = executionInterface.form;
|
|
8089
|
+
const fieldMappings = form.fieldMappings ?? {};
|
|
8090
|
+
const schemaShape = extractZodShape(inputSchema);
|
|
8091
|
+
if (!schemaShape) {
|
|
8092
|
+
return;
|
|
6903
8093
|
}
|
|
6904
|
-
|
|
6905
|
-
|
|
6906
|
-
|
|
6907
|
-
|
|
6908
|
-
|
|
6909
|
-
|
|
6910
|
-
|
|
6911
|
-
|
|
6912
|
-
|
|
6913
|
-
|
|
6914
|
-
|
|
6915
|
-
|
|
6916
|
-
|
|
6917
|
-
|
|
6918
|
-
|
|
6919
|
-
|
|
6920
|
-
|
|
6921
|
-
|
|
6922
|
-
|
|
6923
|
-
|
|
6924
|
-
|
|
6925
|
-
type: "workflow",
|
|
6926
|
-
contextType: "step-started",
|
|
6927
|
-
stepId: step.id,
|
|
6928
|
-
stepStatus: "started",
|
|
6929
|
-
input: truncateForLogging(stepInput),
|
|
6930
|
-
startTime: stepStartTime
|
|
6931
|
-
});
|
|
6932
|
-
try {
|
|
6933
|
-
const rawOutput = await step.handler(stepInput, {
|
|
6934
|
-
executionId: context.executionId,
|
|
6935
|
-
organizationId: context.organizationId,
|
|
6936
|
-
organizationName: context.organizationName,
|
|
6937
|
-
resourceId: workflow.config.resourceId,
|
|
6938
|
-
sessionId: context.sessionId,
|
|
6939
|
-
sessionTurnNumber: context.sessionTurnNumber,
|
|
6940
|
-
parentExecutionId: context.parentExecutionId,
|
|
6941
|
-
executionDepth: context.executionDepth,
|
|
6942
|
-
adapters: context.adapters,
|
|
6943
|
-
store: /* @__PURE__ */ new Map(),
|
|
6944
|
-
logger: {
|
|
6945
|
-
debug: (msg) => console.log(`[debug] ${msg}`),
|
|
6946
|
-
info: (msg) => console.log(`[info] ${msg}`),
|
|
6947
|
-
warn: (msg) => console.warn(`[warn] ${msg}`),
|
|
6948
|
-
error: (msg) => console.error(`[error] ${msg}`)
|
|
6949
|
-
}
|
|
6950
|
-
});
|
|
6951
|
-
currentData = step.outputSchema.parse(rawOutput);
|
|
6952
|
-
const stepEndTime = Date.now();
|
|
6953
|
-
const nextStepId = resolveNext(step.next, currentData);
|
|
6954
|
-
postLog("info", `Step '${step.name}' completed (${stepEndTime - stepStartTime}ms)`, {
|
|
6955
|
-
type: "workflow",
|
|
6956
|
-
contextType: "step-completed",
|
|
6957
|
-
stepId: step.id,
|
|
6958
|
-
stepStatus: "completed",
|
|
6959
|
-
output: truncateForLogging(currentData),
|
|
6960
|
-
duration: stepEndTime - stepStartTime,
|
|
6961
|
-
isTerminal: nextStepId === null,
|
|
6962
|
-
startTime: stepStartTime,
|
|
6963
|
-
endTime: stepEndTime
|
|
6964
|
-
});
|
|
6965
|
-
if (step.next?.type === "conditional" && nextStepId !== null) {
|
|
6966
|
-
postLog("info", `Routing from '${step.name}' to '${nextStepId}'`, {
|
|
6967
|
-
type: "workflow",
|
|
6968
|
-
contextType: "conditional-route",
|
|
6969
|
-
stepId: step.id,
|
|
6970
|
-
target: nextStepId
|
|
6971
|
-
});
|
|
8094
|
+
const schemaFieldNames = Object.keys(schemaShape);
|
|
8095
|
+
const formToSchemaMap = /* @__PURE__ */ new Map();
|
|
8096
|
+
for (const field of form.fields) {
|
|
8097
|
+
const schemaKey = fieldMappings[field.name] ?? field.name;
|
|
8098
|
+
formToSchemaMap.set(field.name, schemaKey);
|
|
8099
|
+
}
|
|
8100
|
+
for (const schemaFieldName of schemaFieldNames) {
|
|
8101
|
+
const schemaField = schemaShape[schemaFieldName];
|
|
8102
|
+
const isRequired = !isZodOptional(schemaField);
|
|
8103
|
+
let hasFormField = false;
|
|
8104
|
+
for (const [formFieldName, mappedSchemaName] of Array.from(formToSchemaMap.entries())) {
|
|
8105
|
+
if (mappedSchemaName === schemaFieldName) {
|
|
8106
|
+
hasFormField = true;
|
|
8107
|
+
const formField = form.fields.find((f4) => f4.name === formFieldName);
|
|
8108
|
+
if (isRequired && !formField?.required) {
|
|
8109
|
+
throw new RegistryValidationError(
|
|
8110
|
+
orgName,
|
|
8111
|
+
resourceId,
|
|
8112
|
+
`interface.form.fields.${formFieldName}`,
|
|
8113
|
+
`ExecutionInterface field "${formFieldName}" should be required to match inputSchema field "${schemaFieldName}" in ${orgName}/${resourceId}`
|
|
8114
|
+
);
|
|
6972
8115
|
}
|
|
6973
|
-
|
|
6974
|
-
} catch (err) {
|
|
6975
|
-
const stepEndTime = Date.now();
|
|
6976
|
-
postLog("error", `Step '${step.name}' failed: ${String(err)}`, {
|
|
6977
|
-
type: "workflow",
|
|
6978
|
-
contextType: "step-failed",
|
|
6979
|
-
stepId: step.id,
|
|
6980
|
-
stepStatus: "failed",
|
|
6981
|
-
error: String(err),
|
|
6982
|
-
duration: stepEndTime - stepStartTime,
|
|
6983
|
-
startTime: stepStartTime,
|
|
6984
|
-
endTime: stepEndTime
|
|
6985
|
-
});
|
|
6986
|
-
throw err;
|
|
8116
|
+
break;
|
|
6987
8117
|
}
|
|
6988
8118
|
}
|
|
6989
|
-
if (
|
|
6990
|
-
|
|
8119
|
+
if (isRequired && !hasFormField) {
|
|
8120
|
+
throw new RegistryValidationError(
|
|
8121
|
+
orgName,
|
|
8122
|
+
resourceId,
|
|
8123
|
+
"interface.form.fields",
|
|
8124
|
+
`ExecutionInterface missing required field "${schemaFieldName}" from inputSchema in ${orgName}/${resourceId}`
|
|
8125
|
+
);
|
|
6991
8126
|
}
|
|
6992
|
-
return { output: currentData, logs };
|
|
6993
|
-
} finally {
|
|
6994
|
-
restore();
|
|
6995
8127
|
}
|
|
6996
|
-
|
|
6997
|
-
|
|
6998
|
-
|
|
6999
|
-
|
|
7000
|
-
|
|
7001
|
-
|
|
7002
|
-
|
|
7003
|
-
|
|
7004
|
-
|
|
7005
|
-
return {
|
|
7006
|
-
executionId: params.executionId,
|
|
7007
|
-
organizationId: params.organizationId,
|
|
7008
|
-
organizationName: params.organizationName,
|
|
7009
|
-
resourceId: params.resourceId,
|
|
7010
|
-
sessionId: params.sessionId,
|
|
7011
|
-
sessionTurnNumber: params.sessionTurnNumber,
|
|
7012
|
-
parentExecutionId: params.parentExecutionId,
|
|
7013
|
-
executionDepth: params.executionDepth,
|
|
7014
|
-
signal: params.signal,
|
|
7015
|
-
store: /* @__PURE__ */ new Map(),
|
|
7016
|
-
logger: {
|
|
7017
|
-
debug: (msg) => {
|
|
7018
|
-
console.log(`[debug] ${msg}`);
|
|
7019
|
-
postLog("info", msg);
|
|
7020
|
-
},
|
|
7021
|
-
info: (msg) => {
|
|
7022
|
-
console.log(`[info] ${msg}`);
|
|
7023
|
-
postLog("info", msg);
|
|
7024
|
-
},
|
|
7025
|
-
warn: (msg) => {
|
|
7026
|
-
console.warn(`[warn] ${msg}`);
|
|
7027
|
-
postLog("warn", msg);
|
|
7028
|
-
},
|
|
7029
|
-
error: (msg) => {
|
|
7030
|
-
console.error(`[error] ${msg}`);
|
|
7031
|
-
postLog("error", msg);
|
|
7032
|
-
}
|
|
7033
|
-
},
|
|
7034
|
-
onMessageEvent: async (event) => {
|
|
7035
|
-
parentPort.postMessage({ type: "message-event", executionId, event });
|
|
8128
|
+
for (const [formFieldName, schemaFieldName] of Array.from(formToSchemaMap.entries())) {
|
|
8129
|
+
if (schemaFieldName.includes(".")) {
|
|
8130
|
+
const topLevelField = schemaFieldName.split(".")[0];
|
|
8131
|
+
throw new RegistryValidationError(
|
|
8132
|
+
orgName,
|
|
8133
|
+
resourceId,
|
|
8134
|
+
`interface.form.fields.${formFieldName}`,
|
|
8135
|
+
`ExecutionInterface field "${formFieldName}" uses nested notation. Flatten the inputSchema by moving nested fields to top-level (e.g., "${topLevelField}.x" \u2192 "x") in ${orgName}/${resourceId}`
|
|
8136
|
+
);
|
|
7036
8137
|
}
|
|
7037
|
-
|
|
7038
|
-
|
|
7039
|
-
|
|
7040
|
-
|
|
7041
|
-
|
|
7042
|
-
|
|
7043
|
-
|
|
7044
|
-
parentPort.on("message", async (msg) => {
|
|
7045
|
-
if (msg.type === "manifest") {
|
|
7046
|
-
parentPort.postMessage({
|
|
7047
|
-
type: "manifest",
|
|
7048
|
-
workflows: (org.workflows ?? []).map((w2) => ({
|
|
7049
|
-
resourceId: w2.config.resourceId,
|
|
7050
|
-
name: w2.config.name,
|
|
7051
|
-
type: w2.config.type,
|
|
7052
|
-
status: w2.config.status,
|
|
7053
|
-
description: w2.config.description,
|
|
7054
|
-
version: w2.config.version,
|
|
7055
|
-
links: w2.config.links,
|
|
7056
|
-
category: w2.config.category,
|
|
7057
|
-
contract: {
|
|
7058
|
-
inputSchema: safeZodToJsonSchema(w2.contract?.inputSchema),
|
|
7059
|
-
outputSchema: safeZodToJsonSchema(w2.contract?.outputSchema)
|
|
7060
|
-
},
|
|
7061
|
-
steps: Object.values(w2.steps).map((step) => ({
|
|
7062
|
-
id: step.id,
|
|
7063
|
-
name: step.name,
|
|
7064
|
-
description: step.description,
|
|
7065
|
-
inputSchema: safeZodToJsonSchema(step.inputSchema),
|
|
7066
|
-
outputSchema: safeZodToJsonSchema(step.outputSchema),
|
|
7067
|
-
next: serializeNext(step.next)
|
|
7068
|
-
})),
|
|
7069
|
-
entryPoint: w2.entryPoint
|
|
7070
|
-
})),
|
|
7071
|
-
agents: (org.agents ?? []).map((a3) => ({
|
|
7072
|
-
resourceId: a3.config.resourceId,
|
|
7073
|
-
name: a3.config.name,
|
|
7074
|
-
type: a3.config.type,
|
|
7075
|
-
status: a3.config.status,
|
|
7076
|
-
description: a3.config.description,
|
|
7077
|
-
version: a3.config.version,
|
|
7078
|
-
links: a3.config.links,
|
|
7079
|
-
category: a3.config.category,
|
|
7080
|
-
contract: {
|
|
7081
|
-
inputSchema: safeZodToJsonSchema(a3.contract?.inputSchema),
|
|
7082
|
-
outputSchema: safeZodToJsonSchema(a3.contract?.outputSchema)
|
|
7083
|
-
}
|
|
7084
|
-
})),
|
|
7085
|
-
triggers: org.triggers ?? [],
|
|
7086
|
-
integrations: org.integrations ?? [],
|
|
7087
|
-
humanCheckpoints: org.humanCheckpoints ?? [],
|
|
7088
|
-
relationships: org.relationships ?? void 0
|
|
7089
|
-
});
|
|
7090
|
-
return;
|
|
8138
|
+
if (!schemaFieldNames.includes(schemaFieldName)) {
|
|
8139
|
+
throw new RegistryValidationError(
|
|
8140
|
+
orgName,
|
|
8141
|
+
resourceId,
|
|
8142
|
+
`interface.form.fields.${formFieldName}`,
|
|
8143
|
+
`ExecutionInterface field "${formFieldName}" maps to non-existent schema field "${schemaFieldName}" in ${orgName}/${resourceId}`
|
|
8144
|
+
);
|
|
7091
8145
|
}
|
|
7092
|
-
|
|
7093
|
-
|
|
7094
|
-
|
|
8146
|
+
}
|
|
8147
|
+
}
|
|
8148
|
+
function extractZodShape(schema) {
|
|
8149
|
+
if ("shape" in schema && typeof schema.shape === "object") {
|
|
8150
|
+
return schema.shape;
|
|
8151
|
+
}
|
|
8152
|
+
if ("_def" in schema) {
|
|
8153
|
+
const def = schema._def;
|
|
8154
|
+
if (def.innerType) {
|
|
8155
|
+
return extractZodShape(def.innerType);
|
|
7095
8156
|
}
|
|
7096
|
-
if (
|
|
7097
|
-
|
|
7098
|
-
return;
|
|
8157
|
+
if (def.schema) {
|
|
8158
|
+
return extractZodShape(def.schema);
|
|
7099
8159
|
}
|
|
7100
|
-
|
|
7101
|
-
|
|
7102
|
-
localAbortController.abort();
|
|
7103
|
-
return;
|
|
7104
|
-
}
|
|
7105
|
-
if (msg.type === "execute") {
|
|
7106
|
-
const {
|
|
7107
|
-
resourceId,
|
|
7108
|
-
executionId,
|
|
7109
|
-
input,
|
|
7110
|
-
organizationId,
|
|
7111
|
-
organizationName,
|
|
7112
|
-
sessionId,
|
|
7113
|
-
sessionTurnNumber,
|
|
7114
|
-
parentExecutionId,
|
|
7115
|
-
executionDepth
|
|
7116
|
-
} = msg;
|
|
7117
|
-
console.log(`[SDK-WORKER] Execute request: resourceId=${resourceId}, executionId=${executionId}`);
|
|
7118
|
-
localAbortController = new AbortController();
|
|
7119
|
-
const workflow = workflows.get(resourceId);
|
|
7120
|
-
if (workflow) {
|
|
7121
|
-
const startTime = Date.now();
|
|
7122
|
-
try {
|
|
7123
|
-
console.log(`[SDK-WORKER] Running workflow '${resourceId}' (${Object.keys(workflow.steps).length} steps)`);
|
|
7124
|
-
const { output, logs } = await executeWorkflow(workflow, input, {
|
|
7125
|
-
executionId,
|
|
7126
|
-
organizationId: organizationId ?? "",
|
|
7127
|
-
organizationName: organizationName ?? "",
|
|
7128
|
-
sessionId,
|
|
7129
|
-
sessionTurnNumber,
|
|
7130
|
-
parentExecutionId,
|
|
7131
|
-
executionDepth: executionDepth ?? 0
|
|
7132
|
-
});
|
|
7133
|
-
const durationMs = Date.now() - startTime;
|
|
7134
|
-
console.log(`[SDK-WORKER] Workflow '${resourceId}' completed (${durationMs}ms)`);
|
|
7135
|
-
parentPort.postMessage({ type: "result", status: "completed", output, logs, metrics: { durationMs } });
|
|
7136
|
-
} catch (err) {
|
|
7137
|
-
const durationMs = Date.now() - startTime;
|
|
7138
|
-
console.error(`[SDK-WORKER] Workflow '${resourceId}' failed (${durationMs}ms): ${String(err)}`);
|
|
7139
|
-
parentPort.postMessage({
|
|
7140
|
-
type: "result",
|
|
7141
|
-
status: "failed",
|
|
7142
|
-
error: String(err),
|
|
7143
|
-
logs: [],
|
|
7144
|
-
metrics: { durationMs }
|
|
7145
|
-
});
|
|
7146
|
-
}
|
|
7147
|
-
return;
|
|
7148
|
-
}
|
|
7149
|
-
const agentDef = agents.get(resourceId);
|
|
7150
|
-
if (agentDef) {
|
|
7151
|
-
const logs = [];
|
|
7152
|
-
const { restore } = captureConsole(executionId, logs);
|
|
7153
|
-
const startTime = Date.now();
|
|
7154
|
-
try {
|
|
7155
|
-
console.log(`[SDK-WORKER] Running agent '${resourceId}' (${agentDef.tools.length} tools)`);
|
|
7156
|
-
const adapterFactory = createPostMessageAdapterFactory();
|
|
7157
|
-
const agentInstance = new Agent(agentDef, adapterFactory);
|
|
7158
|
-
const context = buildWorkerExecutionContext({
|
|
7159
|
-
executionId,
|
|
7160
|
-
organizationId: organizationId ?? "",
|
|
7161
|
-
organizationName: organizationName ?? "",
|
|
7162
|
-
resourceId,
|
|
7163
|
-
sessionId,
|
|
7164
|
-
sessionTurnNumber,
|
|
7165
|
-
parentExecutionId,
|
|
7166
|
-
executionDepth: executionDepth ?? 0,
|
|
7167
|
-
signal: localAbortController.signal
|
|
7168
|
-
});
|
|
7169
|
-
const output = await agentInstance.execute(input, context);
|
|
7170
|
-
const durationMs = Date.now() - startTime;
|
|
7171
|
-
console.log(`[SDK-WORKER] Agent '${resourceId}' completed (${durationMs}ms)`);
|
|
7172
|
-
parentPort.postMessage({ type: "result", status: "completed", output, logs, metrics: { durationMs } });
|
|
7173
|
-
} catch (err) {
|
|
7174
|
-
const durationMs = Date.now() - startTime;
|
|
7175
|
-
const errorMessage = err?.message ?? String(err);
|
|
7176
|
-
err?.code ?? "unknown";
|
|
7177
|
-
const errorName = err?.name ?? err?.constructor?.name ?? "Error";
|
|
7178
|
-
console.error(`[SDK-WORKER] Agent '${resourceId}' failed (${durationMs}ms): [${errorName}] ${errorMessage}`);
|
|
7179
|
-
parentPort.postMessage({
|
|
7180
|
-
type: "result",
|
|
7181
|
-
status: "failed",
|
|
7182
|
-
error: `${errorName}: ${errorMessage}`,
|
|
7183
|
-
logs,
|
|
7184
|
-
metrics: { durationMs }
|
|
7185
|
-
});
|
|
7186
|
-
} finally {
|
|
7187
|
-
restore();
|
|
7188
|
-
}
|
|
7189
|
-
return;
|
|
7190
|
-
}
|
|
7191
|
-
console.error(`[SDK-WORKER] Resource not found: ${resourceId}`);
|
|
7192
|
-
parentPort.postMessage({
|
|
7193
|
-
type: "result",
|
|
7194
|
-
status: "failed",
|
|
7195
|
-
error: `Resource not found: ${resourceId}`,
|
|
7196
|
-
logs: []
|
|
7197
|
-
});
|
|
7198
|
-
}
|
|
7199
|
-
});
|
|
8160
|
+
}
|
|
8161
|
+
return null;
|
|
7200
8162
|
}
|
|
7201
|
-
|
|
7202
|
-
|
|
7203
|
-
void (async () => {
|
|
7204
|
-
const mod = await import(modulePath);
|
|
7205
|
-
startWorker(mod.default);
|
|
7206
|
-
})();
|
|
8163
|
+
function isZodOptional(schema) {
|
|
8164
|
+
return schema.isOptional();
|
|
7207
8165
|
}
|
|
7208
|
-
|
|
7209
|
-
|
|
7210
|
-
|
|
7211
|
-
|
|
7212
|
-
|
|
7213
|
-
|
|
7214
|
-
|
|
7215
|
-
|
|
7216
|
-
|
|
7217
|
-
|
|
7218
|
-
|
|
7219
|
-
|
|
7220
|
-
|
|
7221
|
-
|
|
7222
|
-
|
|
7223
|
-
|
|
7224
|
-
|
|
7225
|
-
|
|
7226
|
-
|
|
7227
|
-
|
|
7228
|
-
|
|
7229
|
-
|
|
8166
|
+
function validateRelationships(orgName, resources) {
|
|
8167
|
+
if (!resources.relationships && !resources.triggers && !resources.externalResources && !resources.humanCheckpoints)
|
|
8168
|
+
return;
|
|
8169
|
+
const validAgentIds = new Set(resources.agents?.map((a3) => a3.config.resourceId) ?? []);
|
|
8170
|
+
const validWorkflowIds = new Set(resources.workflows?.map((w2) => w2.config.resourceId) ?? []);
|
|
8171
|
+
const validIntegrationIds = new Set(resources.integrations?.map((i) => i.resourceId) ?? []);
|
|
8172
|
+
const validTriggerIds = new Set(resources.triggers?.map((t) => t.resourceId) ?? []);
|
|
8173
|
+
const allInternalIds = /* @__PURE__ */ new Set([
|
|
8174
|
+
...Array.from(validAgentIds),
|
|
8175
|
+
...Array.from(validWorkflowIds),
|
|
8176
|
+
...Array.from(validTriggerIds),
|
|
8177
|
+
...Array.from(validIntegrationIds)
|
|
8178
|
+
]);
|
|
8179
|
+
validateTriggers(orgName, resources.triggers ?? []);
|
|
8180
|
+
validateResourceRelationships(
|
|
8181
|
+
orgName,
|
|
8182
|
+
resources.relationships ?? {},
|
|
8183
|
+
validAgentIds,
|
|
8184
|
+
validWorkflowIds,
|
|
8185
|
+
validIntegrationIds,
|
|
8186
|
+
validTriggerIds
|
|
8187
|
+
);
|
|
8188
|
+
validateExternalResources(
|
|
8189
|
+
orgName,
|
|
8190
|
+
resources.externalResources ?? [],
|
|
8191
|
+
allInternalIds,
|
|
8192
|
+
validAgentIds,
|
|
8193
|
+
validWorkflowIds,
|
|
8194
|
+
validIntegrationIds
|
|
8195
|
+
);
|
|
8196
|
+
validateHumanCheckpoints(orgName, resources.humanCheckpoints ?? [], allInternalIds, validAgentIds, validWorkflowIds);
|
|
7230
8197
|
}
|
|
7231
|
-
|
|
7232
|
-
const context = options.context ?? {};
|
|
7233
|
-
const { output, logs } = await executeWorkflow(definition, input, {
|
|
7234
|
-
executionId: context.executionId ?? `test-${Date.now()}`,
|
|
7235
|
-
organizationId: context.organizationId ?? "test-org",
|
|
7236
|
-
organizationName: context.organizationName ?? "Test Organization",
|
|
7237
|
-
sessionId: context.sessionId,
|
|
7238
|
-
sessionTurnNumber: context.sessionTurnNumber,
|
|
7239
|
-
parentExecutionId: context.parentExecutionId,
|
|
7240
|
-
executionDepth: context.executionDepth ?? 0,
|
|
7241
|
-
adapters: options.adapters
|
|
7242
|
-
});
|
|
7243
|
-
return {
|
|
7244
|
-
output,
|
|
7245
|
-
logs,
|
|
7246
|
-
stepEvents: extractStepEvents(logs)
|
|
7247
|
-
};
|
|
8198
|
+
function validateTriggers(_orgName, _triggers, _validAgentIds, _validWorkflowIds) {
|
|
7248
8199
|
}
|
|
7249
|
-
|
|
7250
|
-
|
|
7251
|
-
|
|
7252
|
-
|
|
7253
|
-
super(message);
|
|
7254
|
-
this.orgName = orgName;
|
|
7255
|
-
this.resourceId = resourceId;
|
|
7256
|
-
this.field = field;
|
|
7257
|
-
this.name = "RegistryValidationError";
|
|
7258
|
-
}
|
|
7259
|
-
};
|
|
7260
|
-
function validateDeploymentSpec(orgName, resources) {
|
|
7261
|
-
const seenIds = /* @__PURE__ */ new Set();
|
|
7262
|
-
resources.workflows?.forEach((workflow) => {
|
|
7263
|
-
const id = workflow.config.resourceId;
|
|
7264
|
-
if (seenIds.has(id)) {
|
|
8200
|
+
function validateResourceRelationships(orgName, relationships, validAgentIds, validWorkflowIds, validIntegrationIds, validTriggerIds) {
|
|
8201
|
+
for (const [resourceId, declaration] of Object.entries(relationships)) {
|
|
8202
|
+
const resourceExists = validAgentIds.has(resourceId) || validWorkflowIds.has(resourceId) || validTriggerIds.has(resourceId);
|
|
8203
|
+
if (!resourceExists) {
|
|
7265
8204
|
throw new RegistryValidationError(
|
|
7266
8205
|
orgName,
|
|
7267
|
-
|
|
8206
|
+
resourceId,
|
|
7268
8207
|
null,
|
|
7269
|
-
`
|
|
8208
|
+
`[${orgName}] Relationship declared for non-existent resource: ${resourceId}`
|
|
7270
8209
|
);
|
|
7271
8210
|
}
|
|
7272
|
-
|
|
7273
|
-
|
|
7274
|
-
|
|
7275
|
-
|
|
7276
|
-
|
|
7277
|
-
|
|
7278
|
-
|
|
7279
|
-
|
|
7280
|
-
|
|
7281
|
-
|
|
7282
|
-
|
|
8211
|
+
declaration.triggers?.agents?.forEach((agentId) => {
|
|
8212
|
+
if (!validAgentIds.has(agentId)) {
|
|
8213
|
+
throw new RegistryValidationError(
|
|
8214
|
+
orgName,
|
|
8215
|
+
resourceId,
|
|
8216
|
+
"triggers.agents",
|
|
8217
|
+
`[${orgName}] Resource '${resourceId}' triggers non-existent agent: ${agentId}`
|
|
8218
|
+
);
|
|
8219
|
+
}
|
|
8220
|
+
});
|
|
8221
|
+
declaration.triggers?.workflows?.forEach((workflowId) => {
|
|
8222
|
+
if (!validWorkflowIds.has(workflowId)) {
|
|
8223
|
+
throw new RegistryValidationError(
|
|
8224
|
+
orgName,
|
|
8225
|
+
resourceId,
|
|
8226
|
+
"triggers.workflows",
|
|
8227
|
+
`[${orgName}] Resource '${resourceId}' triggers non-existent workflow: ${workflowId}`
|
|
8228
|
+
);
|
|
8229
|
+
}
|
|
8230
|
+
});
|
|
8231
|
+
declaration.uses?.integrations?.forEach((integrationId) => {
|
|
8232
|
+
if (!validIntegrationIds.has(integrationId)) {
|
|
8233
|
+
throw new RegistryValidationError(
|
|
8234
|
+
orgName,
|
|
8235
|
+
resourceId,
|
|
8236
|
+
"uses.integrations",
|
|
8237
|
+
`[${orgName}] Resource '${resourceId}' uses non-existent integration: ${integrationId}`
|
|
8238
|
+
);
|
|
8239
|
+
}
|
|
8240
|
+
});
|
|
8241
|
+
}
|
|
8242
|
+
}
|
|
8243
|
+
function validateExternalResources(orgName, externalResources, allInternalIds, validAgentIds, validWorkflowIds, validIntegrationIds) {
|
|
8244
|
+
externalResources.forEach((external) => {
|
|
8245
|
+
if (allInternalIds.has(external.resourceId)) {
|
|
7283
8246
|
throw new RegistryValidationError(
|
|
7284
8247
|
orgName,
|
|
7285
|
-
|
|
8248
|
+
external.resourceId,
|
|
7286
8249
|
null,
|
|
7287
|
-
`
|
|
8250
|
+
`[${orgName}] External resource ID '${external.resourceId}' conflicts with internal resource ID`
|
|
7288
8251
|
);
|
|
7289
8252
|
}
|
|
7290
|
-
|
|
7291
|
-
|
|
7292
|
-
|
|
7293
|
-
|
|
7294
|
-
|
|
8253
|
+
external.triggers?.agents?.forEach((agentId) => {
|
|
8254
|
+
if (!validAgentIds.has(agentId)) {
|
|
8255
|
+
throw new RegistryValidationError(
|
|
8256
|
+
orgName,
|
|
8257
|
+
external.resourceId,
|
|
8258
|
+
"triggers.agents",
|
|
8259
|
+
`[${orgName}] External resource '${external.resourceId}' triggers non-existent agent: ${agentId}`
|
|
8260
|
+
);
|
|
8261
|
+
}
|
|
8262
|
+
});
|
|
8263
|
+
external.triggers?.workflows?.forEach((workflowId) => {
|
|
8264
|
+
if (!validWorkflowIds.has(workflowId)) {
|
|
8265
|
+
throw new RegistryValidationError(
|
|
8266
|
+
orgName,
|
|
8267
|
+
external.resourceId,
|
|
8268
|
+
"triggers.workflows",
|
|
8269
|
+
`[${orgName}] External resource '${external.resourceId}' triggers non-existent workflow: ${workflowId}`
|
|
8270
|
+
);
|
|
8271
|
+
}
|
|
8272
|
+
});
|
|
8273
|
+
external.uses?.integrations?.forEach((integrationId) => {
|
|
8274
|
+
if (!validIntegrationIds.has(integrationId)) {
|
|
8275
|
+
throw new RegistryValidationError(
|
|
8276
|
+
orgName,
|
|
8277
|
+
external.resourceId,
|
|
8278
|
+
"uses.integrations",
|
|
8279
|
+
`[${orgName}] External resource '${external.resourceId}' uses non-existent integration: ${integrationId}`
|
|
8280
|
+
);
|
|
8281
|
+
}
|
|
8282
|
+
});
|
|
7295
8283
|
});
|
|
7296
8284
|
}
|
|
7297
|
-
function
|
|
7298
|
-
|
|
7299
|
-
|
|
7300
|
-
} catch (error) {
|
|
7301
|
-
if (error instanceof ModelConfigError) {
|
|
8285
|
+
function validateHumanCheckpoints(orgName, humanCheckpoints, allInternalIds, validAgentIds, validWorkflowIds) {
|
|
8286
|
+
humanCheckpoints.forEach((humanCheckpoint) => {
|
|
8287
|
+
if (allInternalIds.has(humanCheckpoint.resourceId)) {
|
|
7302
8288
|
throw new RegistryValidationError(
|
|
7303
8289
|
orgName,
|
|
7304
|
-
resourceId,
|
|
7305
|
-
|
|
7306
|
-
`
|
|
8290
|
+
humanCheckpoint.resourceId,
|
|
8291
|
+
null,
|
|
8292
|
+
`[${orgName}] Human checkpoint ID '${humanCheckpoint.resourceId}' conflicts with internal resource ID`
|
|
7307
8293
|
);
|
|
7308
8294
|
}
|
|
7309
|
-
|
|
7310
|
-
|
|
8295
|
+
humanCheckpoint.requestedBy?.agents?.forEach((agentId) => {
|
|
8296
|
+
if (!validAgentIds.has(agentId)) {
|
|
8297
|
+
throw new RegistryValidationError(
|
|
8298
|
+
orgName,
|
|
8299
|
+
humanCheckpoint.resourceId,
|
|
8300
|
+
"requestedBy.agents",
|
|
8301
|
+
`[${orgName}] Human checkpoint '${humanCheckpoint.resourceId}' requestedBy non-existent agent: ${agentId}`
|
|
8302
|
+
);
|
|
8303
|
+
}
|
|
8304
|
+
});
|
|
8305
|
+
humanCheckpoint.requestedBy?.workflows?.forEach((workflowId) => {
|
|
8306
|
+
if (!validWorkflowIds.has(workflowId)) {
|
|
8307
|
+
throw new RegistryValidationError(
|
|
8308
|
+
orgName,
|
|
8309
|
+
humanCheckpoint.resourceId,
|
|
8310
|
+
"requestedBy.workflows",
|
|
8311
|
+
`[${orgName}] Human checkpoint '${humanCheckpoint.resourceId}' requestedBy non-existent workflow: ${workflowId}`
|
|
8312
|
+
);
|
|
8313
|
+
}
|
|
8314
|
+
});
|
|
8315
|
+
humanCheckpoint.routesTo?.agents?.forEach((agentId) => {
|
|
8316
|
+
if (!validAgentIds.has(agentId)) {
|
|
8317
|
+
throw new RegistryValidationError(
|
|
8318
|
+
orgName,
|
|
8319
|
+
humanCheckpoint.resourceId,
|
|
8320
|
+
"routesTo.agents",
|
|
8321
|
+
`[${orgName}] Human checkpoint '${humanCheckpoint.resourceId}' routesTo non-existent agent: ${agentId}`
|
|
8322
|
+
);
|
|
8323
|
+
}
|
|
8324
|
+
});
|
|
8325
|
+
humanCheckpoint.routesTo?.workflows?.forEach((workflowId) => {
|
|
8326
|
+
if (!validWorkflowIds.has(workflowId)) {
|
|
8327
|
+
throw new RegistryValidationError(
|
|
8328
|
+
orgName,
|
|
8329
|
+
humanCheckpoint.resourceId,
|
|
8330
|
+
"routesTo.workflows",
|
|
8331
|
+
`[${orgName}] Human checkpoint '${humanCheckpoint.resourceId}' routesTo non-existent workflow: ${workflowId}`
|
|
8332
|
+
);
|
|
8333
|
+
}
|
|
8334
|
+
});
|
|
8335
|
+
});
|
|
7311
8336
|
}
|
|
7312
|
-
|
|
7313
|
-
|
|
7314
|
-
|
|
7315
|
-
|
|
7316
|
-
|
|
7317
|
-
|
|
7318
|
-
|
|
7319
|
-
|
|
7320
|
-
|
|
7321
|
-
|
|
7322
|
-
|
|
7323
|
-
|
|
8337
|
+
var listBuilderStageKeys = Object.keys(LEAD_GEN_STAGE_CATALOG);
|
|
8338
|
+
var ListBuilderStageKeySchema = z.enum(listBuilderStageKeys);
|
|
8339
|
+
|
|
8340
|
+
// src/worker/list-builder-workflow.ts
|
|
8341
|
+
var ListBuilderResultSchema = z.object({
|
|
8342
|
+
entity: z.enum(["company", "contact"]),
|
|
8343
|
+
id: z.string().min(1),
|
|
8344
|
+
status: ProcessingStageStatusSchema,
|
|
8345
|
+
stageKey: ListBuilderStageKeySchema.optional(),
|
|
8346
|
+
data: z.unknown().optional()
|
|
8347
|
+
});
|
|
8348
|
+
z.array(ListBuilderResultSchema);
|
|
8349
|
+
|
|
8350
|
+
// src/worker/index.ts
|
|
8351
|
+
function captureConsole(executionId, logs) {
|
|
8352
|
+
const origLog = console.log;
|
|
8353
|
+
const origWarn = console.warn;
|
|
8354
|
+
const origError = console.error;
|
|
8355
|
+
const postLog = (level, message, logContext) => {
|
|
8356
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
8357
|
+
const entry = { level, message, timestamp, context: logContext };
|
|
8358
|
+
logs.push(entry);
|
|
8359
|
+
parentPort?.postMessage({
|
|
8360
|
+
type: "log",
|
|
8361
|
+
entry: { level, message, timestamp, executionId, context: logContext }
|
|
8362
|
+
});
|
|
8363
|
+
};
|
|
8364
|
+
const capture = (level, orig) => (...args) => {
|
|
8365
|
+
postLog(level, args.map(String).join(" "));
|
|
8366
|
+
orig(...args);
|
|
8367
|
+
};
|
|
8368
|
+
console.log = capture("info", origLog);
|
|
8369
|
+
console.warn = capture("warn", origWarn);
|
|
8370
|
+
console.error = capture("error", origError);
|
|
8371
|
+
return {
|
|
8372
|
+
restore: () => {
|
|
8373
|
+
console.log = origLog;
|
|
8374
|
+
console.warn = origWarn;
|
|
8375
|
+
console.error = origError;
|
|
8376
|
+
},
|
|
8377
|
+
postLog
|
|
8378
|
+
};
|
|
8379
|
+
}
|
|
8380
|
+
var LOG_STRING_TRUNCATE_LIMIT = 200;
|
|
8381
|
+
function truncateForLogging(value) {
|
|
8382
|
+
if (value === null || value === void 0) return value;
|
|
8383
|
+
if (typeof value === "string") {
|
|
8384
|
+
return value.length > LOG_STRING_TRUNCATE_LIMIT ? value.slice(0, LOG_STRING_TRUNCATE_LIMIT) + `\u2026 [${value.length} chars]` : value;
|
|
7324
8385
|
}
|
|
7325
|
-
|
|
7326
|
-
|
|
7327
|
-
const isRequired = !isZodOptional(schemaField);
|
|
7328
|
-
let hasFormField = false;
|
|
7329
|
-
for (const [formFieldName, mappedSchemaName] of Array.from(formToSchemaMap.entries())) {
|
|
7330
|
-
if (mappedSchemaName === schemaFieldName) {
|
|
7331
|
-
hasFormField = true;
|
|
7332
|
-
const formField = form.fields.find((f4) => f4.name === formFieldName);
|
|
7333
|
-
if (isRequired && !formField?.required) {
|
|
7334
|
-
throw new RegistryValidationError(
|
|
7335
|
-
orgName,
|
|
7336
|
-
resourceId,
|
|
7337
|
-
`interface.form.fields.${formFieldName}`,
|
|
7338
|
-
`ExecutionInterface field "${formFieldName}" should be required to match inputSchema field "${schemaFieldName}" in ${orgName}/${resourceId}`
|
|
7339
|
-
);
|
|
7340
|
-
}
|
|
7341
|
-
break;
|
|
7342
|
-
}
|
|
7343
|
-
}
|
|
7344
|
-
if (isRequired && !hasFormField) {
|
|
7345
|
-
throw new RegistryValidationError(
|
|
7346
|
-
orgName,
|
|
7347
|
-
resourceId,
|
|
7348
|
-
"interface.form.fields",
|
|
7349
|
-
`ExecutionInterface missing required field "${schemaFieldName}" from inputSchema in ${orgName}/${resourceId}`
|
|
7350
|
-
);
|
|
7351
|
-
}
|
|
8386
|
+
if (Array.isArray(value)) {
|
|
8387
|
+
return value.map(truncateForLogging);
|
|
7352
8388
|
}
|
|
7353
|
-
|
|
7354
|
-
|
|
7355
|
-
|
|
7356
|
-
|
|
7357
|
-
orgName,
|
|
7358
|
-
resourceId,
|
|
7359
|
-
`interface.form.fields.${formFieldName}`,
|
|
7360
|
-
`ExecutionInterface field "${formFieldName}" uses nested notation. Flatten the inputSchema by moving nested fields to top-level (e.g., "${topLevelField}.x" \u2192 "x") in ${orgName}/${resourceId}`
|
|
7361
|
-
);
|
|
7362
|
-
}
|
|
7363
|
-
if (!schemaFieldNames.includes(schemaFieldName)) {
|
|
7364
|
-
throw new RegistryValidationError(
|
|
7365
|
-
orgName,
|
|
7366
|
-
resourceId,
|
|
7367
|
-
`interface.form.fields.${formFieldName}`,
|
|
7368
|
-
`ExecutionInterface field "${formFieldName}" maps to non-existent schema field "${schemaFieldName}" in ${orgName}/${resourceId}`
|
|
7369
|
-
);
|
|
8389
|
+
if (typeof value === "object") {
|
|
8390
|
+
const result = {};
|
|
8391
|
+
for (const [k2, v2] of Object.entries(value)) {
|
|
8392
|
+
result[k2] = truncateForLogging(v2);
|
|
7370
8393
|
}
|
|
8394
|
+
return result;
|
|
7371
8395
|
}
|
|
8396
|
+
return value;
|
|
7372
8397
|
}
|
|
7373
|
-
function
|
|
7374
|
-
if (
|
|
7375
|
-
|
|
8398
|
+
function resolveNext(next, data) {
|
|
8399
|
+
if (next === null) return null;
|
|
8400
|
+
if (next.type === "linear") return next.target;
|
|
8401
|
+
for (const route of next.routes) {
|
|
8402
|
+
if (route.condition(data)) return route.target;
|
|
7376
8403
|
}
|
|
7377
|
-
|
|
7378
|
-
|
|
7379
|
-
|
|
7380
|
-
|
|
7381
|
-
|
|
7382
|
-
|
|
7383
|
-
|
|
8404
|
+
return next.default;
|
|
8405
|
+
}
|
|
8406
|
+
function safeZodToJsonSchema(schema) {
|
|
8407
|
+
if (!schema || typeof schema !== "object" || !("parse" in schema)) return void 0;
|
|
8408
|
+
try {
|
|
8409
|
+
const result = zodToJsonSchema(schema, { $refStrategy: "none", errorMessages: true });
|
|
8410
|
+
if (result && typeof result === "object" && Object.keys(result).some((k2) => k2 !== "$schema")) {
|
|
8411
|
+
return result;
|
|
7384
8412
|
}
|
|
8413
|
+
} catch {
|
|
7385
8414
|
}
|
|
7386
|
-
return
|
|
8415
|
+
return void 0;
|
|
7387
8416
|
}
|
|
7388
|
-
function
|
|
7389
|
-
|
|
8417
|
+
function serializeNext(next) {
|
|
8418
|
+
if (next === null) return null;
|
|
8419
|
+
if (next.type === "linear") return { type: "linear", target: next.target };
|
|
8420
|
+
return { type: "conditional", routes: next.routes.map((r2) => ({ target: r2.target })), default: next.default };
|
|
7390
8421
|
}
|
|
7391
|
-
function
|
|
7392
|
-
|
|
7393
|
-
|
|
7394
|
-
|
|
7395
|
-
|
|
7396
|
-
|
|
7397
|
-
|
|
7398
|
-
|
|
7399
|
-
|
|
7400
|
-
|
|
7401
|
-
|
|
7402
|
-
|
|
7403
|
-
|
|
7404
|
-
|
|
7405
|
-
|
|
7406
|
-
|
|
7407
|
-
|
|
7408
|
-
|
|
7409
|
-
|
|
7410
|
-
|
|
7411
|
-
|
|
7412
|
-
|
|
7413
|
-
|
|
7414
|
-
|
|
7415
|
-
|
|
7416
|
-
|
|
7417
|
-
|
|
7418
|
-
|
|
7419
|
-
|
|
7420
|
-
|
|
7421
|
-
|
|
8422
|
+
async function executeWorkflow(workflow, input, context) {
|
|
8423
|
+
const logs = [];
|
|
8424
|
+
const { restore, postLog } = captureConsole(context.executionId, logs);
|
|
8425
|
+
try {
|
|
8426
|
+
let currentData = workflow.contract.inputSchema ? workflow.contract.inputSchema.parse(input) : input;
|
|
8427
|
+
let stepId = workflow.entryPoint;
|
|
8428
|
+
while (stepId !== null) {
|
|
8429
|
+
const step = workflow.steps[stepId];
|
|
8430
|
+
if (!step) {
|
|
8431
|
+
throw new Error(`Step '${stepId}' not found in workflow '${workflow.config.resourceId}'`);
|
|
8432
|
+
}
|
|
8433
|
+
const stepStartTime = Date.now();
|
|
8434
|
+
const stepInput = step.inputSchema.parse(currentData);
|
|
8435
|
+
postLog("info", `Step '${step.name}' started`, {
|
|
8436
|
+
type: "workflow",
|
|
8437
|
+
contextType: "step-started",
|
|
8438
|
+
stepId: step.id,
|
|
8439
|
+
stepStatus: "started",
|
|
8440
|
+
input: truncateForLogging(stepInput),
|
|
8441
|
+
startTime: stepStartTime
|
|
8442
|
+
});
|
|
8443
|
+
try {
|
|
8444
|
+
const rawOutput = await step.handler(stepInput, {
|
|
8445
|
+
executionId: context.executionId,
|
|
8446
|
+
organizationId: context.organizationId,
|
|
8447
|
+
organizationName: context.organizationName,
|
|
8448
|
+
resourceId: workflow.config.resourceId,
|
|
8449
|
+
sessionId: context.sessionId,
|
|
8450
|
+
sessionTurnNumber: context.sessionTurnNumber,
|
|
8451
|
+
parentExecutionId: context.parentExecutionId,
|
|
8452
|
+
executionDepth: context.executionDepth,
|
|
8453
|
+
adapters: context.adapters,
|
|
8454
|
+
store: /* @__PURE__ */ new Map(),
|
|
8455
|
+
logger: {
|
|
8456
|
+
debug: (msg) => console.log(`[debug] ${msg}`),
|
|
8457
|
+
info: (msg) => console.log(`[info] ${msg}`),
|
|
8458
|
+
warn: (msg) => console.warn(`[warn] ${msg}`),
|
|
8459
|
+
error: (msg) => console.error(`[error] ${msg}`)
|
|
8460
|
+
}
|
|
8461
|
+
});
|
|
8462
|
+
currentData = step.outputSchema.parse(rawOutput);
|
|
8463
|
+
const stepEndTime = Date.now();
|
|
8464
|
+
const nextStepId = resolveNext(step.next, currentData);
|
|
8465
|
+
postLog("info", `Step '${step.name}' completed (${stepEndTime - stepStartTime}ms)`, {
|
|
8466
|
+
type: "workflow",
|
|
8467
|
+
contextType: "step-completed",
|
|
8468
|
+
stepId: step.id,
|
|
8469
|
+
stepStatus: "completed",
|
|
8470
|
+
output: truncateForLogging(currentData),
|
|
8471
|
+
duration: stepEndTime - stepStartTime,
|
|
8472
|
+
isTerminal: nextStepId === null,
|
|
8473
|
+
startTime: stepStartTime,
|
|
8474
|
+
endTime: stepEndTime
|
|
8475
|
+
});
|
|
8476
|
+
if (step.next?.type === "conditional" && nextStepId !== null) {
|
|
8477
|
+
postLog("info", `Routing from '${step.name}' to '${nextStepId}'`, {
|
|
8478
|
+
type: "workflow",
|
|
8479
|
+
contextType: "conditional-route",
|
|
8480
|
+
stepId: step.id,
|
|
8481
|
+
target: nextStepId
|
|
8482
|
+
});
|
|
8483
|
+
}
|
|
8484
|
+
stepId = nextStepId;
|
|
8485
|
+
} catch (err) {
|
|
8486
|
+
const stepEndTime = Date.now();
|
|
8487
|
+
postLog("error", `Step '${step.name}' failed: ${String(err)}`, {
|
|
8488
|
+
type: "workflow",
|
|
8489
|
+
contextType: "step-failed",
|
|
8490
|
+
stepId: step.id,
|
|
8491
|
+
stepStatus: "failed",
|
|
8492
|
+
error: String(err),
|
|
8493
|
+
duration: stepEndTime - stepStartTime,
|
|
8494
|
+
startTime: stepStartTime,
|
|
8495
|
+
endTime: stepEndTime
|
|
8496
|
+
});
|
|
8497
|
+
throw err;
|
|
8498
|
+
}
|
|
8499
|
+
}
|
|
8500
|
+
if (workflow.contract.outputSchema) {
|
|
8501
|
+
currentData = workflow.contract.outputSchema.parse(currentData);
|
|
8502
|
+
}
|
|
8503
|
+
return { output: currentData, logs };
|
|
8504
|
+
} finally {
|
|
8505
|
+
restore();
|
|
8506
|
+
}
|
|
7422
8507
|
}
|
|
7423
|
-
function
|
|
8508
|
+
function buildWorkerExecutionContext(params) {
|
|
8509
|
+
const { executionId } = params;
|
|
8510
|
+
const postLog = (level, message) => {
|
|
8511
|
+
parentPort.postMessage({
|
|
8512
|
+
type: "log",
|
|
8513
|
+
entry: { level, message, timestamp: (/* @__PURE__ */ new Date()).toISOString(), executionId }
|
|
8514
|
+
});
|
|
8515
|
+
};
|
|
8516
|
+
return {
|
|
8517
|
+
executionId: params.executionId,
|
|
8518
|
+
organizationId: params.organizationId,
|
|
8519
|
+
organizationName: params.organizationName,
|
|
8520
|
+
resourceId: params.resourceId,
|
|
8521
|
+
sessionId: params.sessionId,
|
|
8522
|
+
sessionTurnNumber: params.sessionTurnNumber,
|
|
8523
|
+
parentExecutionId: params.parentExecutionId,
|
|
8524
|
+
executionDepth: params.executionDepth,
|
|
8525
|
+
signal: params.signal,
|
|
8526
|
+
store: /* @__PURE__ */ new Map(),
|
|
8527
|
+
logger: {
|
|
8528
|
+
debug: (msg) => {
|
|
8529
|
+
console.log(`[debug] ${msg}`);
|
|
8530
|
+
postLog("info", msg);
|
|
8531
|
+
},
|
|
8532
|
+
info: (msg) => {
|
|
8533
|
+
console.log(`[info] ${msg}`);
|
|
8534
|
+
postLog("info", msg);
|
|
8535
|
+
},
|
|
8536
|
+
warn: (msg) => {
|
|
8537
|
+
console.warn(`[warn] ${msg}`);
|
|
8538
|
+
postLog("warn", msg);
|
|
8539
|
+
},
|
|
8540
|
+
error: (msg) => {
|
|
8541
|
+
console.error(`[error] ${msg}`);
|
|
8542
|
+
postLog("error", msg);
|
|
8543
|
+
}
|
|
8544
|
+
},
|
|
8545
|
+
onMessageEvent: async (event) => {
|
|
8546
|
+
parentPort.postMessage({ type: "message-event", executionId, event });
|
|
8547
|
+
}
|
|
8548
|
+
};
|
|
7424
8549
|
}
|
|
7425
|
-
function
|
|
7426
|
-
|
|
7427
|
-
|
|
7428
|
-
|
|
7429
|
-
|
|
7430
|
-
|
|
7431
|
-
|
|
7432
|
-
|
|
7433
|
-
|
|
7434
|
-
|
|
8550
|
+
function startWorker(org) {
|
|
8551
|
+
const workflows = new Map((org.workflows ?? []).map((w2) => [w2.config.resourceId, w2]));
|
|
8552
|
+
const agents = new Map((org.agents ?? []).map((a3) => [a3.config.resourceId, a3]));
|
|
8553
|
+
let localAbortController = new AbortController();
|
|
8554
|
+
console.log(`[SDK-WORKER] Worker started with ${workflows.size} workflow(s), ${agents.size} agent(s)`);
|
|
8555
|
+
parentPort.on("message", async (msg) => {
|
|
8556
|
+
if (msg.type === "manifest") {
|
|
8557
|
+
parentPort.postMessage({
|
|
8558
|
+
type: "manifest",
|
|
8559
|
+
workflows: (org.workflows ?? []).map((w2) => ({
|
|
8560
|
+
resourceId: w2.config.resourceId,
|
|
8561
|
+
name: w2.config.name,
|
|
8562
|
+
type: w2.config.type,
|
|
8563
|
+
status: w2.config.status,
|
|
8564
|
+
description: w2.config.description,
|
|
8565
|
+
version: w2.config.version,
|
|
8566
|
+
links: w2.config.links,
|
|
8567
|
+
category: w2.config.category,
|
|
8568
|
+
contract: {
|
|
8569
|
+
inputSchema: safeZodToJsonSchema(w2.contract?.inputSchema),
|
|
8570
|
+
outputSchema: safeZodToJsonSchema(w2.contract?.outputSchema)
|
|
8571
|
+
},
|
|
8572
|
+
steps: Object.values(w2.steps).map((step) => ({
|
|
8573
|
+
id: step.id,
|
|
8574
|
+
name: step.name,
|
|
8575
|
+
description: step.description,
|
|
8576
|
+
inputSchema: safeZodToJsonSchema(step.inputSchema),
|
|
8577
|
+
outputSchema: safeZodToJsonSchema(step.outputSchema),
|
|
8578
|
+
next: serializeNext(step.next)
|
|
8579
|
+
})),
|
|
8580
|
+
entryPoint: w2.entryPoint
|
|
8581
|
+
})),
|
|
8582
|
+
agents: (org.agents ?? []).map((a3) => ({
|
|
8583
|
+
resourceId: a3.config.resourceId,
|
|
8584
|
+
name: a3.config.name,
|
|
8585
|
+
type: a3.config.type,
|
|
8586
|
+
status: a3.config.status,
|
|
8587
|
+
description: a3.config.description,
|
|
8588
|
+
version: a3.config.version,
|
|
8589
|
+
links: a3.config.links,
|
|
8590
|
+
category: a3.config.category,
|
|
8591
|
+
contract: {
|
|
8592
|
+
inputSchema: safeZodToJsonSchema(a3.contract?.inputSchema),
|
|
8593
|
+
outputSchema: safeZodToJsonSchema(a3.contract?.outputSchema)
|
|
8594
|
+
}
|
|
8595
|
+
})),
|
|
8596
|
+
triggers: org.triggers ?? [],
|
|
8597
|
+
integrations: org.integrations ?? [],
|
|
8598
|
+
humanCheckpoints: org.humanCheckpoints ?? [],
|
|
8599
|
+
relationships: org.relationships ?? void 0
|
|
8600
|
+
});
|
|
8601
|
+
return;
|
|
8602
|
+
}
|
|
8603
|
+
if (msg.type === "tool-result") {
|
|
8604
|
+
handleToolResult(msg);
|
|
8605
|
+
return;
|
|
8606
|
+
}
|
|
8607
|
+
if (msg.type === "credential-result") {
|
|
8608
|
+
handleCredentialResult(msg);
|
|
8609
|
+
return;
|
|
8610
|
+
}
|
|
8611
|
+
if (msg.type === "abort") {
|
|
8612
|
+
console.log("[SDK-WORKER] Abort requested by parent");
|
|
8613
|
+
localAbortController.abort();
|
|
8614
|
+
return;
|
|
7435
8615
|
}
|
|
7436
|
-
|
|
7437
|
-
|
|
7438
|
-
|
|
7439
|
-
|
|
7440
|
-
|
|
7441
|
-
|
|
7442
|
-
|
|
7443
|
-
|
|
7444
|
-
|
|
7445
|
-
|
|
7446
|
-
|
|
7447
|
-
|
|
7448
|
-
|
|
7449
|
-
|
|
7450
|
-
|
|
7451
|
-
|
|
7452
|
-
|
|
7453
|
-
|
|
8616
|
+
if (msg.type === "execute") {
|
|
8617
|
+
const {
|
|
8618
|
+
resourceId,
|
|
8619
|
+
executionId,
|
|
8620
|
+
input,
|
|
8621
|
+
organizationId,
|
|
8622
|
+
organizationName,
|
|
8623
|
+
sessionId,
|
|
8624
|
+
sessionTurnNumber,
|
|
8625
|
+
parentExecutionId,
|
|
8626
|
+
executionDepth
|
|
8627
|
+
} = msg;
|
|
8628
|
+
console.log(`[SDK-WORKER] Execute request: resourceId=${resourceId}, executionId=${executionId}`);
|
|
8629
|
+
localAbortController = new AbortController();
|
|
8630
|
+
const workflow = workflows.get(resourceId);
|
|
8631
|
+
if (workflow) {
|
|
8632
|
+
const startTime = Date.now();
|
|
8633
|
+
try {
|
|
8634
|
+
console.log(`[SDK-WORKER] Running workflow '${resourceId}' (${Object.keys(workflow.steps).length} steps)`);
|
|
8635
|
+
const { output, logs } = await executeWorkflow(workflow, input, {
|
|
8636
|
+
executionId,
|
|
8637
|
+
organizationId: organizationId ?? "",
|
|
8638
|
+
organizationName: organizationName ?? "",
|
|
8639
|
+
sessionId,
|
|
8640
|
+
sessionTurnNumber,
|
|
8641
|
+
parentExecutionId,
|
|
8642
|
+
executionDepth: executionDepth ?? 0
|
|
8643
|
+
});
|
|
8644
|
+
const durationMs = Date.now() - startTime;
|
|
8645
|
+
console.log(`[SDK-WORKER] Workflow '${resourceId}' completed (${durationMs}ms)`);
|
|
8646
|
+
parentPort.postMessage({ type: "result", status: "completed", output, logs, metrics: { durationMs } });
|
|
8647
|
+
} catch (err) {
|
|
8648
|
+
const durationMs = Date.now() - startTime;
|
|
8649
|
+
console.error(`[SDK-WORKER] Workflow '${resourceId}' failed (${durationMs}ms): ${String(err)}`);
|
|
8650
|
+
parentPort.postMessage({
|
|
8651
|
+
type: "result",
|
|
8652
|
+
status: "failed",
|
|
8653
|
+
error: String(err),
|
|
8654
|
+
logs: [],
|
|
8655
|
+
metrics: { durationMs }
|
|
8656
|
+
});
|
|
8657
|
+
}
|
|
8658
|
+
return;
|
|
7454
8659
|
}
|
|
7455
|
-
|
|
7456
|
-
|
|
7457
|
-
|
|
7458
|
-
|
|
7459
|
-
|
|
7460
|
-
|
|
7461
|
-
|
|
7462
|
-
|
|
7463
|
-
|
|
8660
|
+
const agentDef = agents.get(resourceId);
|
|
8661
|
+
if (agentDef) {
|
|
8662
|
+
const logs = [];
|
|
8663
|
+
const { restore } = captureConsole(executionId, logs);
|
|
8664
|
+
const startTime = Date.now();
|
|
8665
|
+
try {
|
|
8666
|
+
console.log(`[SDK-WORKER] Running agent '${resourceId}' (${agentDef.tools.length} tools)`);
|
|
8667
|
+
const adapterFactory = createPostMessageAdapterFactory();
|
|
8668
|
+
const agentInstance = new Agent(agentDef, adapterFactory);
|
|
8669
|
+
const context = buildWorkerExecutionContext({
|
|
8670
|
+
executionId,
|
|
8671
|
+
organizationId: organizationId ?? "",
|
|
8672
|
+
organizationName: organizationName ?? "",
|
|
8673
|
+
resourceId,
|
|
8674
|
+
sessionId,
|
|
8675
|
+
sessionTurnNumber,
|
|
8676
|
+
parentExecutionId,
|
|
8677
|
+
executionDepth: executionDepth ?? 0,
|
|
8678
|
+
signal: localAbortController.signal
|
|
8679
|
+
});
|
|
8680
|
+
const output = await agentInstance.execute(input, context);
|
|
8681
|
+
const durationMs = Date.now() - startTime;
|
|
8682
|
+
console.log(`[SDK-WORKER] Agent '${resourceId}' completed (${durationMs}ms)`);
|
|
8683
|
+
parentPort.postMessage({ type: "result", status: "completed", output, logs, metrics: { durationMs } });
|
|
8684
|
+
} catch (err) {
|
|
8685
|
+
const durationMs = Date.now() - startTime;
|
|
8686
|
+
const errorMessage = err?.message ?? String(err);
|
|
8687
|
+
err?.code ?? "unknown";
|
|
8688
|
+
const errorName = err?.name ?? err?.constructor?.name ?? "Error";
|
|
8689
|
+
console.error(`[SDK-WORKER] Agent '${resourceId}' failed (${durationMs}ms): [${errorName}] ${errorMessage}`);
|
|
8690
|
+
parentPort.postMessage({
|
|
8691
|
+
type: "result",
|
|
8692
|
+
status: "failed",
|
|
8693
|
+
error: `${errorName}: ${errorMessage}`,
|
|
8694
|
+
logs,
|
|
8695
|
+
metrics: { durationMs }
|
|
8696
|
+
});
|
|
8697
|
+
} finally {
|
|
8698
|
+
restore();
|
|
8699
|
+
}
|
|
8700
|
+
return;
|
|
7464
8701
|
}
|
|
7465
|
-
|
|
7466
|
-
|
|
7467
|
-
|
|
7468
|
-
|
|
7469
|
-
|
|
7470
|
-
|
|
7471
|
-
|
|
7472
|
-
orgName,
|
|
7473
|
-
external.resourceId,
|
|
7474
|
-
null,
|
|
7475
|
-
`[${orgName}] External resource ID '${external.resourceId}' conflicts with internal resource ID`
|
|
7476
|
-
);
|
|
8702
|
+
console.error(`[SDK-WORKER] Resource not found: ${resourceId}`);
|
|
8703
|
+
parentPort.postMessage({
|
|
8704
|
+
type: "result",
|
|
8705
|
+
status: "failed",
|
|
8706
|
+
error: `Resource not found: ${resourceId}`,
|
|
8707
|
+
logs: []
|
|
8708
|
+
});
|
|
7477
8709
|
}
|
|
7478
|
-
external.triggers?.agents?.forEach((agentId) => {
|
|
7479
|
-
if (!validAgentIds.has(agentId)) {
|
|
7480
|
-
throw new RegistryValidationError(
|
|
7481
|
-
orgName,
|
|
7482
|
-
external.resourceId,
|
|
7483
|
-
"triggers.agents",
|
|
7484
|
-
`[${orgName}] External resource '${external.resourceId}' triggers non-existent agent: ${agentId}`
|
|
7485
|
-
);
|
|
7486
|
-
}
|
|
7487
|
-
});
|
|
7488
|
-
external.triggers?.workflows?.forEach((workflowId) => {
|
|
7489
|
-
if (!validWorkflowIds.has(workflowId)) {
|
|
7490
|
-
throw new RegistryValidationError(
|
|
7491
|
-
orgName,
|
|
7492
|
-
external.resourceId,
|
|
7493
|
-
"triggers.workflows",
|
|
7494
|
-
`[${orgName}] External resource '${external.resourceId}' triggers non-existent workflow: ${workflowId}`
|
|
7495
|
-
);
|
|
7496
|
-
}
|
|
7497
|
-
});
|
|
7498
|
-
external.uses?.integrations?.forEach((integrationId) => {
|
|
7499
|
-
if (!validIntegrationIds.has(integrationId)) {
|
|
7500
|
-
throw new RegistryValidationError(
|
|
7501
|
-
orgName,
|
|
7502
|
-
external.resourceId,
|
|
7503
|
-
"uses.integrations",
|
|
7504
|
-
`[${orgName}] External resource '${external.resourceId}' uses non-existent integration: ${integrationId}`
|
|
7505
|
-
);
|
|
7506
|
-
}
|
|
7507
|
-
});
|
|
7508
8710
|
});
|
|
7509
8711
|
}
|
|
7510
|
-
|
|
7511
|
-
|
|
7512
|
-
|
|
7513
|
-
|
|
7514
|
-
|
|
7515
|
-
|
|
7516
|
-
|
|
7517
|
-
|
|
7518
|
-
|
|
8712
|
+
if (workerData != null && workerData.kind === "static") {
|
|
8713
|
+
const { modulePath } = workerData;
|
|
8714
|
+
void (async () => {
|
|
8715
|
+
const mod = await import(modulePath);
|
|
8716
|
+
startWorker(mod.default);
|
|
8717
|
+
})();
|
|
8718
|
+
}
|
|
8719
|
+
|
|
8720
|
+
// src/test-utils/workflow.ts
|
|
8721
|
+
function extractStepEvents(logs) {
|
|
8722
|
+
return logs.flatMap((log) => {
|
|
8723
|
+
const context = log.context;
|
|
8724
|
+
if (!context || context.type !== "workflow" || typeof context.contextType !== "string") {
|
|
8725
|
+
return [];
|
|
7519
8726
|
}
|
|
7520
|
-
|
|
7521
|
-
|
|
7522
|
-
|
|
7523
|
-
|
|
7524
|
-
|
|
7525
|
-
|
|
7526
|
-
|
|
7527
|
-
|
|
7528
|
-
|
|
7529
|
-
|
|
7530
|
-
|
|
7531
|
-
if (!validWorkflowIds.has(workflowId)) {
|
|
7532
|
-
throw new RegistryValidationError(
|
|
7533
|
-
orgName,
|
|
7534
|
-
humanCheckpoint.resourceId,
|
|
7535
|
-
"requestedBy.workflows",
|
|
7536
|
-
`[${orgName}] Human checkpoint '${humanCheckpoint.resourceId}' requestedBy non-existent workflow: ${workflowId}`
|
|
7537
|
-
);
|
|
7538
|
-
}
|
|
7539
|
-
});
|
|
7540
|
-
humanCheckpoint.routesTo?.agents?.forEach((agentId) => {
|
|
7541
|
-
if (!validAgentIds.has(agentId)) {
|
|
7542
|
-
throw new RegistryValidationError(
|
|
7543
|
-
orgName,
|
|
7544
|
-
humanCheckpoint.resourceId,
|
|
7545
|
-
"routesTo.agents",
|
|
7546
|
-
`[${orgName}] Human checkpoint '${humanCheckpoint.resourceId}' routesTo non-existent agent: ${agentId}`
|
|
7547
|
-
);
|
|
7548
|
-
}
|
|
7549
|
-
});
|
|
7550
|
-
humanCheckpoint.routesTo?.workflows?.forEach((workflowId) => {
|
|
7551
|
-
if (!validWorkflowIds.has(workflowId)) {
|
|
7552
|
-
throw new RegistryValidationError(
|
|
7553
|
-
orgName,
|
|
7554
|
-
humanCheckpoint.resourceId,
|
|
7555
|
-
"routesTo.workflows",
|
|
7556
|
-
`[${orgName}] Human checkpoint '${humanCheckpoint.resourceId}' routesTo non-existent workflow: ${workflowId}`
|
|
7557
|
-
);
|
|
8727
|
+
return [
|
|
8728
|
+
{
|
|
8729
|
+
type: context.contextType,
|
|
8730
|
+
stepId: typeof context.stepId === "string" ? context.stepId : void 0,
|
|
8731
|
+
stepStatus: typeof context.stepStatus === "string" ? context.stepStatus : void 0,
|
|
8732
|
+
input: context.input,
|
|
8733
|
+
output: context.output,
|
|
8734
|
+
error: context.error,
|
|
8735
|
+
duration: typeof context.duration === "number" ? context.duration : void 0,
|
|
8736
|
+
target: typeof context.target === "string" ? context.target : void 0,
|
|
8737
|
+
raw: context
|
|
7558
8738
|
}
|
|
7559
|
-
|
|
8739
|
+
];
|
|
8740
|
+
});
|
|
8741
|
+
}
|
|
8742
|
+
async function runWorkflow(definition, input, options = {}) {
|
|
8743
|
+
const context = options.context ?? {};
|
|
8744
|
+
const { output, logs } = await executeWorkflow(definition, input, {
|
|
8745
|
+
executionId: context.executionId ?? `test-${Date.now()}`,
|
|
8746
|
+
organizationId: context.organizationId ?? "test-org",
|
|
8747
|
+
organizationName: context.organizationName ?? "Test Organization",
|
|
8748
|
+
sessionId: context.sessionId,
|
|
8749
|
+
sessionTurnNumber: context.sessionTurnNumber,
|
|
8750
|
+
parentExecutionId: context.parentExecutionId,
|
|
8751
|
+
executionDepth: context.executionDepth ?? 0,
|
|
8752
|
+
adapters: options.adapters
|
|
7560
8753
|
});
|
|
8754
|
+
return {
|
|
8755
|
+
output,
|
|
8756
|
+
logs,
|
|
8757
|
+
stepEvents: extractStepEvents(logs)
|
|
8758
|
+
};
|
|
7561
8759
|
}
|
|
7562
8760
|
|
|
7563
8761
|
// src/test-utils/registry.ts
|
|
@@ -24328,7 +25526,14 @@ var mockCrm = (overrides) => createMockAdapter(
|
|
|
24328
25526
|
overrides
|
|
24329
25527
|
);
|
|
24330
25528
|
var mockList = (overrides) => createMockAdapter(
|
|
24331
|
-
[
|
|
25529
|
+
[
|
|
25530
|
+
"getConfig",
|
|
25531
|
+
"recordExecution",
|
|
25532
|
+
"updateCompanyStage",
|
|
25533
|
+
"updateContactStage",
|
|
25534
|
+
"listPendingCompanyIds",
|
|
25535
|
+
"listPendingContactIds"
|
|
25536
|
+
],
|
|
24332
25537
|
overrides
|
|
24333
25538
|
);
|
|
24334
25539
|
var mockPdf = (overrides) => createMockAdapter(["render", "renderToBuffer"], overrides);
|