@synap-core/workspace-templates 0.11.0 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +483 -0
- package/automations/bookmark-enrichment.automation.json +321 -0
- package/automations/github-pr-events.automation.json +505 -0
- package/automations/mail-feed.automation.json +86 -0
- package/automations/ship-a-change-checks-green.automation.json +106 -0
- package/automations/ship-a-change-checks-red.automation.json +106 -0
- package/automations/ship-a-change-deployed.automation.json +56 -0
- package/automations/ship-a-change-pr-merged.automation.json +110 -0
- package/automations/ship-a-change-pr-opened.automation.json +104 -0
- package/automations/url-bookmark-capture.automation.json +132 -0
- package/capabilities/agency-skills.capability.json +157 -0
- package/capabilities/apify.capability.json +265 -0
- package/capabilities/apollo.capability.json +120 -0
- package/capabilities/arch-backend.capability.json +97 -0
- package/capabilities/arch-client-intelligence.capability.json +401 -0
- package/capabilities/backblaze-b2.capability.json +205 -0
- package/capabilities/cal-com.capability.json +266 -0
- package/capabilities/canva.capability.json +274 -0
- package/capabilities/claude-code-routines.capability.json +172 -0
- package/capabilities/claude-managed-agents.capability.json +215 -0
- package/capabilities/client-comms-report.capability.json +246 -0
- package/capabilities/content-idea-to-production.capability.json +29 -0
- package/capabilities/datagouv.capability.json +315 -0
- package/capabilities/discord-bot.capability.json +157 -0
- package/capabilities/dropbox.capability.json +281 -0
- package/capabilities/exa.capability.json +109 -0
- package/capabilities/fal-ai.capability.json +83 -0
- package/capabilities/fal-media-lab.capability.json +158 -0
- package/capabilities/fireflies.capability.json +191 -0
- package/capabilities/freellmapi.capability.json +114 -0
- package/capabilities/generic-apikey.capability.json +92 -0
- package/capabilities/github-merge.capability.json +99 -0
- package/capabilities/github-read.capability.json +325 -0
- package/capabilities/governance-tighten-recommender.capability.json +81 -0
- package/capabilities/jev.capability.json +226 -0
- package/capabilities/lead-conversion-enrollment.capability.json +246 -0
- package/capabilities/mail-feed.capability.json +277 -0
- package/capabilities/mailgun.capability.json +52 -0
- package/capabilities/nango-google.capability.json +639 -0
- package/capabilities/notion.capability.json +417 -0
- package/capabilities/omniroute.capability.json +137 -0
- package/capabilities/posthog-analytics.capability.json +258 -0
- package/capabilities/postiz.capability.json +467 -0
- package/capabilities/proactive-digest.capability.json +190 -0
- package/capabilities/proton.capability.json +288 -0
- package/capabilities/replicate-rvm.capability.json +97 -0
- package/capabilities/research-methods.capability.json +57 -0
- package/capabilities/shopify.capability.json +395 -0
- package/capabilities/slack.capability.json +369 -0
- package/capabilities/stripe.capability.json +420 -0
- package/capabilities/telegram-bridge.capability.json +56 -0
- package/capabilities/treg.capability.json +102 -0
- package/capabilities/unipile-linkedin.capability.json +471 -0
- package/capabilities/vercel.capability.json +424 -0
- package/dist/define-CPS0n8BV.d.ts +1331 -0
- package/dist/index.d.ts +189 -900
- package/dist/index.js +24654 -21639
- package/dist/index.js.map +1 -1
- package/dist/wire.d.ts +222 -0
- package/dist/wire.js +77 -0
- package/dist/wire.js.map +1 -0
- package/package.json +41 -27
- package/packs/bookmark-views-pack.json +33 -0
- package/packs/crm-pack.json +76 -0
- package/packs/customer-profile.json +28 -0
- package/packs/deep-research.playbook.json +30 -0
- package/packs/event-views-pack.json +33 -0
- package/packs/habit-profile.json +27 -0
- package/packs/hr-pack.json +54 -0
- package/packs/invoice-profile.json +28 -0
- package/packs/knowledge-base-pack.json +56 -0
- package/packs/meeting-profile.json +29 -0
- package/packs/product-profile.json +30 -0
- package/packs/project-management-pack.json +49 -0
- package/packs/recipe-profile.json +29 -0
- package/packs/task-views-pack.json +39 -0
- package/retired.yaml +136 -0
- package/skills/app-factory-build-slice/SKILL.md +70 -0
- package/skills/app-factory-build-slice.catalog.json +17 -0
- package/skills/app-factory-design-canvas/SKILL.md +96 -0
- package/skills/app-factory-design-canvas.catalog.json +17 -0
- package/skills/app-factory-design-review/SKILL.md +99 -0
- package/skills/app-factory-design-review.catalog.json +18 -0
- package/skills/app-factory-research/SKILL.md +123 -0
- package/skills/app-factory-research.catalog.json +17 -0
- package/skills/bookmark-enrichment/SKILL.md +40 -0
- package/skills/carousel-format/carousel-format.skill.json +18 -0
- package/skills/collage-broll/collage-broll.skill.json +20 -0
- package/skills/content-taste/content-taste.skill.json +18 -0
- package/skills/creative-director/creative-director.skill.json +18 -0
- package/skills/design-critique/SKILL.md +135 -0
- package/skills/design-critique.catalog.json +12 -0
- package/skills/designing-with-real-components/SKILL.md +140 -0
- package/skills/designing-with-real-components.catalog.json +12 -0
- package/skills/edit-loop/edit-loop.skill.json +25 -0
- package/skills/facecam-edit/facecam-edit.skill.json +24 -0
- package/skills/mapping-the-server/SKILL.md +54 -0
- package/skills/math-explainer-manimgx/math-explainer-manimgx.skill.json +20 -0
- package/skills/motion-quality-gates/motion-quality-gates.skill.json +20 -0
- package/skills/open-design-edit/open-design-edit.skill.json +24 -0
- package/skills/reading-client-progress/SKILL.md +65 -0
- package/skills/routing-to-channels/SKILL.md +54 -0
- package/skills/stellar-scf-grants-advisor/ASSOCIATE-CHEATSHEET.md +133 -0
- package/skills/stellar-scf-grants-advisor/ASSOCIATE-ONBOARDING-GUIDE.md +761 -0
- package/skills/stellar-scf-grants-advisor/CLIENT-FAQ.md +181 -0
- package/skills/stellar-scf-grants-advisor/PARTNER-HANDOVER.md +130 -0
- package/skills/stellar-scf-grants-advisor/SKILL.md +102 -0
- package/skills/stellar-scf-grants-advisor/examples/README.md +43 -0
- package/skills/stellar-scf-grants-advisor/examples/chat-summary-templates.md +158 -0
- package/skills/stellar-scf-grants-advisor/examples/corpus-comparable-rows.md +136 -0
- package/skills/stellar-scf-grants-advisor/examples/q10-team-rewrites.md +109 -0
- package/skills/stellar-scf-grants-advisor/examples/q2-description-rewrites.md +88 -0
- package/skills/stellar-scf-grants-advisor/examples/q6-integration-rewrites.md +107 -0
- package/skills/stellar-scf-grants-advisor/examples/tranche-structures.md +176 -0
- package/skills/stellar-scf-grants-advisor/reference/01-methodology.md +96 -0
- package/skills/stellar-scf-grants-advisor/reference/02-scoring-framework.md +199 -0
- package/skills/stellar-scf-grants-advisor/reference/03-rejection-patterns.md +241 -0
- package/skills/stellar-scf-grants-advisor/reference/04-winner-patterns.md +120 -0
- package/skills/stellar-scf-grants-advisor/reference/05-comeback-patterns.md +92 -0
- package/skills/stellar-scf-grants-advisor/reference/06-budget-benchmarks.md +125 -0
- package/skills/stellar-scf-grants-advisor/reference/07-integration-list.md +147 -0
- package/skills/stellar-scf-grants-advisor/reference/08-abstract-fields.md +258 -0
- package/skills/stellar-scf-grants-advisor/reference/09-build-fields.md +259 -0
- package/skills/stellar-scf-grants-advisor/reference/10-corpus-winners.md +135 -0
- package/skills/stellar-scf-grants-advisor/reference/11-corpus-rejects.md +267 -0
- package/skills/stellar-scf-grants-advisor/reference/12-client-communication.md +131 -0
- package/skills/stellar-scf-grants-advisor/reference/13-excel-output-spec.md +199 -0
- package/skills/stellar-scf-grants-advisor/reference/14-worked-examples.md +160 -0
- package/skills/stellar-scf-grants-advisor/templates/abstract-review-builder.py +253 -0
- package/skills/stellar-scf-grants-advisor/templates/build-review-builder.py +213 -0
- package/skills/video-direction/video-direction.skill.json +20 -0
- package/skills/video-style-vocabulary/video-style-vocabulary.skill.json +20 -0
- package/skills/video-toolbox/video-toolbox.skill.json +20 -0
- package/src/__fixtures__/lifecycle-presets.flat-before.json +205 -0
- package/src/agency-os.yaml +122 -0
- package/src/agent-os-skill-slugs.test.ts +65 -0
- package/src/apify-social-reader.test.ts +317 -0
- package/src/base.template.test.ts +25 -19
- package/src/base.yaml +95 -39
- package/src/blockchain-ecosystem.yaml +1 -0
- package/src/brand-library.yaml +525 -14
- package/src/builder-dev-fold.template.test.ts +113 -0
- package/src/builder.yaml +798 -92
- package/src/business-model-catalog-description.test.ts +47 -0
- package/src/business-model-grp.template.test.ts +214 -0
- package/src/business-model.yaml +598 -0
- package/src/catalog-safety.test.ts +198 -0
- package/src/catalog.template-items.test.ts +75 -0
- package/src/catalog.ts +85 -2
- package/src/civic-france.yaml +102 -0
- package/src/concept-guard.test.ts +28 -8
- package/src/concept-guard.ts +2 -2
- package/src/content-creation.template.test.ts +52 -0
- package/src/content-creation.yaml +192 -0
- package/src/content-os.edit-loop.template.test.ts +210 -0
- package/src/content-os.publish-due-posts.template.test.ts +261 -0
- package/src/content-os.template.test.ts +322 -0
- package/src/content-os.video-takes.template.test.ts +338 -0
- package/src/content-os.work-a-take.template.test.ts +125 -0
- package/src/content-os.yaml +1830 -39
- package/src/content-studio-retired.template.test.ts +82 -0
- package/src/corpus-flow-validity.test.ts +4 -5
- package/src/crm-absorbs-outreach.template.test.ts +117 -0
- package/src/crm-build-plan.template.test.ts +128 -0
- package/src/crm-lists.template.test.ts +96 -0
- package/src/crm-messages-cadence.template.test.ts +164 -0
- package/src/crm-one-send-door.template.test.ts +65 -0
- package/src/crm.yaml +1456 -181
- package/src/decisions-wave.template.test.ts +186 -0
- package/src/define.ts +130 -17
- package/src/design-to-implementation.template.test.ts +94 -0
- package/src/dist-freshness.test.ts +97 -0
- package/src/domain-template-type.test.ts +75 -0
- package/src/ecosystem.yaml +27 -66
- package/src/enterprise-os.yaml +10 -134
- package/src/facecam-edit.audio-studio.test.ts +188 -0
- package/src/fal-generate-image.test.ts +200 -0
- package/src/fal-media-lab-pod-files.test.ts +180 -0
- package/src/finance.yaml +254 -1
- package/src/foundation.yaml +130 -28
- package/src/frame-host-modules.d.mts +6 -0
- package/src/frame-host-modules.mjs +58 -0
- package/src/generate.mjs +9 -3
- package/src/github-merge.test.ts +210 -0
- package/src/grants.yaml +57 -17
- package/src/hr.yaml +39 -6
- package/src/index.ts +36 -1
- package/src/intent.test.ts +161 -0
- package/src/internal-runbook.yaml +19 -1
- package/src/jev.test.ts +356 -0
- package/src/legal.yaml +33 -1
- package/src/life-os.yaml +65 -240
- package/src/lifecycle-coverage.test.ts +124 -0
- package/src/lifecycle-declarations.test.ts +252 -0
- package/src/lifecycle-presets.test.ts +468 -0
- package/src/lifecycle-presets.ts +494 -0
- package/src/lifecycle-stuck.test.ts +46 -0
- package/src/lifecycle-waits.parity.test.ts +319 -0
- package/src/marketing.yaml +108 -4
- package/src/meetings-knowledge.yaml +18 -0
- package/src/networking.yaml +23 -2
- package/src/operations.yaml +304 -4
- package/src/pipeline-views.template.test.ts +88 -0
- package/src/playbook-goal-placeholders.test.ts +57 -0
- package/src/postiz-contract.test.ts +134 -0
- package/src/presentation-declarations.test.ts +174 -0
- package/src/process-contract.validate.test.ts +352 -0
- package/src/project-management.yaml +39 -740
- package/src/publish-body.d.mts +29 -0
- package/src/publish-body.mjs +74 -0
- package/src/publish-body.test.ts +74 -0
- package/src/publish-official-lib.test.ts +176 -0
- package/src/replicate-rvm.test.ts +504 -0
- package/src/research-base.yaml +119 -20
- package/src/research-decision.yaml +60 -3
- package/src/reserved-profile-slugs.test.ts +83 -0
- package/src/retired-goal-kinds.test.ts +58 -0
- package/src/role-reference-and-step-domain.test.ts +192 -0
- package/src/seed-obligation.test.ts +176 -0
- package/src/send-message-maps.test.ts +227 -0
- package/src/shared-role-ssot.test.ts +42 -1
- package/src/ship-a-change.template.test.ts +177 -0
- package/src/skills.test.ts +170 -0
- package/src/social.yaml +85 -27
- package/src/space-packages.freshness.test.ts +97 -0
- package/src/space-packages.generated.ts +40 -0
- package/src/space-packages.test.ts +125 -0
- package/src/space-packages.ts +73 -0
- package/src/start.test.ts +188 -0
- package/src/task-intents.test.ts +293 -0
- package/src/templates.ts +21639 -21522
- package/src/types.ts +443 -60
- package/src/unipile-publish-post.test.ts +162 -0
- package/src/validate-flow.drift.test.ts +2 -3
- package/src/validate-flow.ts +32 -2
- package/src/validate-onboarding.test.ts +59 -0
- package/src/validate.test.ts +156 -3
- package/src/validate.ts +1384 -7
- package/src/wire-core.ts +231 -0
- package/src/wire.test.ts +159 -0
- package/src/wire.ts +107 -0
- package/src/__fixtures__/report-automation-flow.json +0 -393
- package/src/agent-fleet.yaml +0 -1645
- package/src/business-developer.template.test.ts +0 -351
- package/src/business-developer.yaml +0 -860
- package/src/content-studio.yaml +0 -361
- package/src/dev-dashboard.yaml +0 -990
- package/src/outreach-comms.yaml +0 -486
- package/src/the-arch.yaml +0 -201
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
{
|
|
2
|
+
"apiVersion": "synap/v1",
|
|
3
|
+
"kind": "capability",
|
|
4
|
+
"meta": {
|
|
5
|
+
"slug": "jev",
|
|
6
|
+
"name": "Jev (TypeSafe decision model)",
|
|
7
|
+
"description": "Ask Jev, TypeSafe's decision model, to pick one option, place something on an ordered scale, or answer yes/no, with calibrated probabilities. Several questions can go in one call. Read-only: nothing is saved unless you choose to. Bring your own TypeSafe API key (console.typesafe.ai).",
|
|
8
|
+
"tags": ["capability"],
|
|
9
|
+
"isPublic": true,
|
|
10
|
+
"syncByDefault": true
|
|
11
|
+
},
|
|
12
|
+
"spec": {
|
|
13
|
+
"key": "jev",
|
|
14
|
+
"name": "Jev Decision Model",
|
|
15
|
+
"description": "Jev decision model (TypeSafe System One): choose, score, yes/no, batched. Bring your own key.",
|
|
16
|
+
"params": [
|
|
17
|
+
{
|
|
18
|
+
"name": "jevApiKey",
|
|
19
|
+
"label": "TypeSafe API key",
|
|
20
|
+
"type": "text",
|
|
21
|
+
"required": true,
|
|
22
|
+
"description": "Your TypeSafe API key from console.typesafe.ai. Stored encrypted in the pod vault; never in the template."
|
|
23
|
+
}
|
|
24
|
+
],
|
|
25
|
+
"vault": [
|
|
26
|
+
{
|
|
27
|
+
"ref": "jevApiKeySecret",
|
|
28
|
+
"name": "{{name}} Jev API key",
|
|
29
|
+
"value": "{{jevApiKey}}",
|
|
30
|
+
"type": "api_key",
|
|
31
|
+
"description": "Jev API key for the jev_api connector."
|
|
32
|
+
}
|
|
33
|
+
],
|
|
34
|
+
"tools": [
|
|
35
|
+
{
|
|
36
|
+
"name": "jev_api",
|
|
37
|
+
"kind": "api",
|
|
38
|
+
"description": "Authenticated HTTP access to TypeSafe's API (https://api.typesafe.ai, POST /v1/systemone). The dispatcher injects the vaulted key as `Authorization: Bearer <key>`; credentialRef is remapped to vault://<id> at apply time.",
|
|
39
|
+
"credentialRef": "jevApiKeySecret",
|
|
40
|
+
"executor": "is-agent",
|
|
41
|
+
"config": {
|
|
42
|
+
"baseUrl": "https://api.typesafe.ai",
|
|
43
|
+
"auth": {
|
|
44
|
+
"in": "header",
|
|
45
|
+
"name": "Authorization",
|
|
46
|
+
"prefix": "Bearer "
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
],
|
|
51
|
+
"skills": [
|
|
52
|
+
{
|
|
53
|
+
"intent": "run_external_job",
|
|
54
|
+
"kind": "code",
|
|
55
|
+
"scope": "pod",
|
|
56
|
+
"requires": ["jev_api"],
|
|
57
|
+
"executionMode": "sync",
|
|
58
|
+
"timeoutSeconds": 60,
|
|
59
|
+
"metadata": {
|
|
60
|
+
"readOnly": true,
|
|
61
|
+
"verbType": "read"
|
|
62
|
+
},
|
|
63
|
+
"name": "jev_choose",
|
|
64
|
+
"description": "Ask Jev to pick ONE option about some content, with a probability per option and Jev's confidence. Read-only: saves nothing. Args: { state: string|object (the content), question: string, options: string[] (2+ keys Jev answers with), descriptions?: { key: what it means }, minConfidence?: number 0-1 }. Optional model: a Jev model name or alias (default jev-latest). Returns { choice, confidence, confident, probabilities, model, usage }. Confidence is advice, never permission to act.",
|
|
65
|
+
"code": "// Jev (TypeSafe System One). One call: POST /v1/systemone { model, state, questions }.\n// callProvider resolves the jev_api tool by NAME and injects the vaulted key as a Bearer header.\n// The model is a call argument, never an install-time value baked into this code: skill code\n// that carries install params can never be re-applied by the pod's capability reconcile.\nconst MODEL = typeof args?.model === 'string' && args.model.trim() ? args.model.trim() : 'jev-latest';\nasync function systemOne(fn, state, questions) {\n const res = await callProvider('jev_api', 'POST', '/v1/systemone', { model: MODEL, state, questions });\n if (typeof res?.status === 'number' && (res.status < 200 || res.status >= 300)) {\n throw new Error(fn + ': Jev answered ' + res.status + ' ' + JSON.stringify(res?.body ?? '').slice(0, 300));\n }\n const out = res?.body ?? res;\n if (!out || typeof out.answers !== 'object') throw new Error(fn + ': Jev returned no answers');\n return out;\n}\nfunction stateOf(fn, args) {\n const st = args?.state;\n if (typeof st === 'string' ? !st.trim() : (st == null || typeof st !== 'object')) {\n throw new Error(fn + ': state is required (the content the question is about: text or JSON)');\n }\n return st;\n}\n\nconst fn = 'jev_choose';\nconst state = stateOf(fn, args);\nconst question = String(args?.question ?? '').trim();\nif (!question) throw new Error(fn + ': question is required');\n// options: the keys Jev answers with; descriptions (optional): what each key means.\nif (!Array.isArray(args?.options)) throw new Error(fn + ': options must be a list of option keys');\nconst keys = args.options.map((o) => String(o ?? '').trim()).filter(Boolean);\nif (keys.length < 2) throw new Error(fn + ': give at least 2 options');\nconst descriptions = args?.descriptions && typeof args.descriptions === 'object' && !Array.isArray(args.descriptions) ? args.descriptions : {};\nconst criteria = Object.fromEntries(keys.map((k) => [k, typeof descriptions[k] === 'string' && descriptions[k].trim() ? descriptions[k].trim() : k]));\nconst out = await systemOne(fn, state, { decision: { type: 'choice', instructions: question, criteria } });\nconst a = out.answers.decision ?? {};\nconst min = Number(args?.minConfidence);\nconst confidence = typeof a.confidence === 'number' ? a.confidence : null;\nconst confident = Number.isFinite(min) ? (confidence ?? 0) >= min : null;\nreturn { choice: a.choice ?? null, confidence, confident, probabilities: a.probabilities ?? {}, model: out.model ?? null, usage: out.usage ?? null };\n",
|
|
66
|
+
"parameters": {
|
|
67
|
+
"state": "string",
|
|
68
|
+
"question": "string",
|
|
69
|
+
"options": "array",
|
|
70
|
+
"descriptions": "object?",
|
|
71
|
+
"minConfidence": "number?",
|
|
72
|
+
"model": "string?"
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"intent": "run_external_job",
|
|
77
|
+
"kind": "code",
|
|
78
|
+
"scope": "pod",
|
|
79
|
+
"requires": ["jev_api"],
|
|
80
|
+
"executionMode": "sync",
|
|
81
|
+
"timeoutSeconds": 60,
|
|
82
|
+
"metadata": {
|
|
83
|
+
"readOnly": true,
|
|
84
|
+
"verbType": "read"
|
|
85
|
+
},
|
|
86
|
+
"name": "jev_score",
|
|
87
|
+
"description": "Ask Jev to place content on an ordered scale (lowest level first). Read-only. Args: { state, question: string, levels: string[] (2+, ordered) }. Optional model: a Jev model name or alias (default jev-latest). Returns { score (may fall between levels), confidence, legend, probabilities, model, usage }.",
|
|
88
|
+
"code": "// Jev (TypeSafe System One). One call: POST /v1/systemone { model, state, questions }.\n// callProvider resolves the jev_api tool by NAME and injects the vaulted key as a Bearer header.\n// The model is a call argument, never an install-time value baked into this code: skill code\n// that carries install params can never be re-applied by the pod's capability reconcile.\nconst MODEL = typeof args?.model === 'string' && args.model.trim() ? args.model.trim() : 'jev-latest';\nasync function systemOne(fn, state, questions) {\n const res = await callProvider('jev_api', 'POST', '/v1/systemone', { model: MODEL, state, questions });\n if (typeof res?.status === 'number' && (res.status < 200 || res.status >= 300)) {\n throw new Error(fn + ': Jev answered ' + res.status + ' ' + JSON.stringify(res?.body ?? '').slice(0, 300));\n }\n const out = res?.body ?? res;\n if (!out || typeof out.answers !== 'object') throw new Error(fn + ': Jev returned no answers');\n return out;\n}\nfunction stateOf(fn, args) {\n const st = args?.state;\n if (typeof st === 'string' ? !st.trim() : (st == null || typeof st !== 'object')) {\n throw new Error(fn + ': state is required (the content the question is about: text or JSON)');\n }\n return st;\n}\n\nconst fn = 'jev_score';\nconst state = stateOf(fn, args);\nconst question = String(args?.question ?? '').trim();\nif (!question) throw new Error(fn + ': question is required');\nconst levels = Array.isArray(args?.levels) ? args.levels.map((l) => String(l).trim()).filter(Boolean) : [];\nif (levels.length < 2) throw new Error(fn + ': levels must list at least 2 ordered levels, lowest first');\nconst out = await systemOne(fn, state, { rating: { type: 'score', instructions: question, criteria: levels } });\nconst a = out.answers.rating ?? {};\nreturn { score: a.score ?? null, confidence: a.confidence ?? null, legend: a.legend ?? null, probabilities: a.probabilities ?? {}, model: out.model ?? null, usage: out.usage ?? null };\n",
|
|
89
|
+
"parameters": {
|
|
90
|
+
"state": "string",
|
|
91
|
+
"question": "string",
|
|
92
|
+
"levels": "array",
|
|
93
|
+
"model": "string?"
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
"intent": "run_external_job",
|
|
98
|
+
"kind": "code",
|
|
99
|
+
"scope": "pod",
|
|
100
|
+
"requires": ["jev_api"],
|
|
101
|
+
"executionMode": "sync",
|
|
102
|
+
"timeoutSeconds": 60,
|
|
103
|
+
"metadata": {
|
|
104
|
+
"readOnly": true,
|
|
105
|
+
"verbType": "read"
|
|
106
|
+
},
|
|
107
|
+
"name": "jev_noul",
|
|
108
|
+
"description": "Ask Jev a yes/no question about content; returns the probability of yes (no confidence field). Read-only. Args: { state, question: string }. Optional model: a Jev model name or alias (default jev-latest). Returns { probabilityYes, model, usage }.",
|
|
109
|
+
"code": "// Jev (TypeSafe System One). One call: POST /v1/systemone { model, state, questions }.\n// callProvider resolves the jev_api tool by NAME and injects the vaulted key as a Bearer header.\n// The model is a call argument, never an install-time value baked into this code: skill code\n// that carries install params can never be re-applied by the pod's capability reconcile.\nconst MODEL = typeof args?.model === 'string' && args.model.trim() ? args.model.trim() : 'jev-latest';\nasync function systemOne(fn, state, questions) {\n const res = await callProvider('jev_api', 'POST', '/v1/systemone', { model: MODEL, state, questions });\n if (typeof res?.status === 'number' && (res.status < 200 || res.status >= 300)) {\n throw new Error(fn + ': Jev answered ' + res.status + ' ' + JSON.stringify(res?.body ?? '').slice(0, 300));\n }\n const out = res?.body ?? res;\n if (!out || typeof out.answers !== 'object') throw new Error(fn + ': Jev returned no answers');\n return out;\n}\nfunction stateOf(fn, args) {\n const st = args?.state;\n if (typeof st === 'string' ? !st.trim() : (st == null || typeof st !== 'object')) {\n throw new Error(fn + ': state is required (the content the question is about: text or JSON)');\n }\n return st;\n}\n\nconst fn = 'jev_noul';\nconst state = stateOf(fn, args);\nconst question = String(args?.question ?? '').trim();\nif (!question) throw new Error(fn + ': question is required (a yes/no question)');\nconst out = await systemOne(fn, state, { answer: { type: 'noul', instructions: question } });\nconst a = out.answers.answer ?? {};\nreturn { probabilityYes: typeof a.noul === 'number' ? a.noul : null, model: out.model ?? null, usage: out.usage ?? null };\n",
|
|
110
|
+
"parameters": {
|
|
111
|
+
"state": "string",
|
|
112
|
+
"question": "string",
|
|
113
|
+
"model": "string?"
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"intent": "run_external_job",
|
|
118
|
+
"kind": "code",
|
|
119
|
+
"scope": "pod",
|
|
120
|
+
"requires": ["jev_api"],
|
|
121
|
+
"executionMode": "sync",
|
|
122
|
+
"timeoutSeconds": 60,
|
|
123
|
+
"metadata": {
|
|
124
|
+
"readOnly": true,
|
|
125
|
+
"verbType": "read"
|
|
126
|
+
},
|
|
127
|
+
"name": "jev_ask",
|
|
128
|
+
"description": "Ask Jev several questions about the same content in ONE call (cheaper and faster than one call each). Read-only. Args: { state, questions: { name: { type: 'choice'|'score'|'noul', instructions, criteria? } } }. Optional model: a Jev model name or alias (default jev-latest). Returns { answers (keyed by your names), model, usage }.",
|
|
129
|
+
"code": "// Jev (TypeSafe System One). One call: POST /v1/systemone { model, state, questions }.\n// callProvider resolves the jev_api tool by NAME and injects the vaulted key as a Bearer header.\n// The model is a call argument, never an install-time value baked into this code: skill code\n// that carries install params can never be re-applied by the pod's capability reconcile.\nconst MODEL = typeof args?.model === 'string' && args.model.trim() ? args.model.trim() : 'jev-latest';\nasync function systemOne(fn, state, questions) {\n const res = await callProvider('jev_api', 'POST', '/v1/systemone', { model: MODEL, state, questions });\n if (typeof res?.status === 'number' && (res.status < 200 || res.status >= 300)) {\n throw new Error(fn + ': Jev answered ' + res.status + ' ' + JSON.stringify(res?.body ?? '').slice(0, 300));\n }\n const out = res?.body ?? res;\n if (!out || typeof out.answers !== 'object') throw new Error(fn + ': Jev returned no answers');\n return out;\n}\nfunction stateOf(fn, args) {\n const st = args?.state;\n if (typeof st === 'string' ? !st.trim() : (st == null || typeof st !== 'object')) {\n throw new Error(fn + ': state is required (the content the question is about: text or JSON)');\n }\n return st;\n}\n\nconst fn = 'jev_ask';\nconst state = stateOf(fn, args);\nconst questions = args?.questions;\nif (!questions || typeof questions !== 'object' || Array.isArray(questions) || Object.keys(questions).length === 0) {\n throw new Error(fn + ': questions must be a non-empty { name: { type: choice|score|noul, instructions, criteria? } } map');\n}\nfor (const [name, q] of Object.entries(questions)) {\n if (!['choice', 'score', 'noul'].includes(q?.type)) throw new Error(fn + ': question ' + name + ' has type ' + q?.type + '; use choice, score or noul');\n}\nconst out = await systemOne(fn, state, questions);\nreturn { answers: out.answers, model: out.model ?? null, usage: out.usage ?? null };\n",
|
|
130
|
+
"parameters": {
|
|
131
|
+
"state": "string",
|
|
132
|
+
"questions": "object",
|
|
133
|
+
"model": "string?"
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
"name": "jev-routing-policy",
|
|
138
|
+
"kind": "instruction",
|
|
139
|
+
"scope": "pod",
|
|
140
|
+
"description": "When to route a decision through Jev, which verb to use, and what to do with a low-confidence answer. Pure know-how.",
|
|
141
|
+
"code": "# Routing a decision through Jev\n\nJev answers typed questions about content you give it (`state`): pick one option (jev_choose), place on an ordered scale (jev_score), yes/no probability (jev_noul), or several at once (jev_ask, one call). It does not write text or look facts up.\n\nBefore you call it, read the person's own policy if they wrote one (a document named \"Jev policy\"): which decisions go to Jev, the minimum confidence, the default options. It wins over this text.\n\nAlways include an abstain option (\"none_of_these\") in a choice. A confidence under the person's minimum is not a decision: say so and ask the person. A Jev answer is advice; any commitment it leads to still goes through the person."
|
|
142
|
+
}
|
|
143
|
+
],
|
|
144
|
+
"provides": ["run_external_job"],
|
|
145
|
+
"playbooks": [
|
|
146
|
+
{
|
|
147
|
+
"name": "Decide with Jev",
|
|
148
|
+
"description": "Frame a decision, ask Jev to choose or score, and record the decision once a person confirms it.",
|
|
149
|
+
"goalTemplate": "Decide: {question}. Options: {options}. Ordered levels instead of options (optional): {levels}. Minimum confidence: {minConfidence}.\n\n1. Restate the question and the options; add 'none_of_these' and the status quo if missing.\n2. If levels are given, call jev_score; otherwise call jev_choose with minConfidence.\n3. Below the minimum confidence, stop and ask the person to choose.\n4. Otherwise propose a decision entity with the choice, Jev's probabilities as rationale, and the other options as alternatives. A person confirms it.",
|
|
150
|
+
"params": [
|
|
151
|
+
{
|
|
152
|
+
"name": "question",
|
|
153
|
+
"label": "Question",
|
|
154
|
+
"type": "text",
|
|
155
|
+
"required": true
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
"name": "options",
|
|
159
|
+
"label": "Options (one per line)",
|
|
160
|
+
"type": "text",
|
|
161
|
+
"required": true
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
"name": "levels",
|
|
165
|
+
"label": "Ordered levels, lowest first (optional)",
|
|
166
|
+
"type": "text",
|
|
167
|
+
"required": false
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
"name": "minConfidence",
|
|
171
|
+
"label": "Minimum confidence (0-1)",
|
|
172
|
+
"type": "text",
|
|
173
|
+
"required": false,
|
|
174
|
+
"default": "0.6"
|
|
175
|
+
}
|
|
176
|
+
],
|
|
177
|
+
"channelSpec": {
|
|
178
|
+
"type": "THREAD",
|
|
179
|
+
"aiReactionMode": "only_mentioned"
|
|
180
|
+
},
|
|
181
|
+
"executor": "is-agent",
|
|
182
|
+
"status": "active",
|
|
183
|
+
"stages": [
|
|
184
|
+
{
|
|
185
|
+
"key": "frame",
|
|
186
|
+
"name": "Frame",
|
|
187
|
+
"category": "started",
|
|
188
|
+
"goal": "Question and options are explicit and mutually exclusive.",
|
|
189
|
+
"grants": [
|
|
190
|
+
{
|
|
191
|
+
"kind": "skill",
|
|
192
|
+
"id": "jev-routing-policy"
|
|
193
|
+
}
|
|
194
|
+
]
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
"key": "ask-jev",
|
|
198
|
+
"name": "Ask Jev",
|
|
199
|
+
"category": "started",
|
|
200
|
+
"goal": "Jev's choice or scores with probabilities.",
|
|
201
|
+
"grants": [
|
|
202
|
+
{
|
|
203
|
+
"kind": "skill",
|
|
204
|
+
"id": "jev_choose"
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
"kind": "skill",
|
|
208
|
+
"id": "jev_score"
|
|
209
|
+
}
|
|
210
|
+
]
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
"key": "record",
|
|
214
|
+
"name": "Record",
|
|
215
|
+
"category": "started",
|
|
216
|
+
"goal": "A decision entity proposed with rationale and alternatives.",
|
|
217
|
+
"gate": {
|
|
218
|
+
"kind": "human"
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
]
|
|
222
|
+
}
|
|
223
|
+
]
|
|
224
|
+
},
|
|
225
|
+
"dependencies": []
|
|
226
|
+
}
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
{
|
|
2
|
+
"apiVersion": "synap/v1",
|
|
3
|
+
"kind": "capability",
|
|
4
|
+
"meta": {
|
|
5
|
+
"slug": "lead-conversion-enrollment",
|
|
6
|
+
"name": "Lead Conversion Enrollment",
|
|
7
|
+
"description": "When a new lead is created, starts the conversion playbook that matches its lead source: Cold Outreach, Inbound, Referral or Standard. Install with the lead-conversion playbooks in the same CRM workspace, then adjust the mapping to your funnel.",
|
|
8
|
+
"tags": [
|
|
9
|
+
"capability"
|
|
10
|
+
],
|
|
11
|
+
"isPublic": true,
|
|
12
|
+
"syncByDefault": true
|
|
13
|
+
},
|
|
14
|
+
"spec": {
|
|
15
|
+
"key": "lead-conversion-enrollment",
|
|
16
|
+
"name": "Lead Conversion Enrollment",
|
|
17
|
+
"description": "The source → playbook router. When a new lead (person) is created, this automation reads the lead's `leadSource` and starts the matching conversion-journey session on it: cold-outreach/linkedin → Cold Outreach, landing-page/inbound-call → Inbound, referral → Referral, everything else → Standard. Pairs with the `lead-conversion` LoopDefinition seed (synap-backend/templates/loops/lead-conversion.loop.json), which materializes those four playbooks — install BOTH into the same CRM workspace so the playbook_run nodes resolve by name. Enrollment is idempotent per lead (runPlaybook idempotentBySubject), so re-firing never double-enrolls. STARTER — edit the source→playbook mapping and the trigger filter to match your funnel.",
|
|
18
|
+
"params": [],
|
|
19
|
+
"vault": [],
|
|
20
|
+
"tools": [],
|
|
21
|
+
"skills": [],
|
|
22
|
+
"provides": [],
|
|
23
|
+
"playbooks": [],
|
|
24
|
+
"automations": [
|
|
25
|
+
{
|
|
26
|
+
"name": "Lead Conversion Enrollment",
|
|
27
|
+
"description": "On new person: read the lead, switch on its `leadSource`, and start the matching conversion playbook on the lead (idempotent per lead). Seeded ACTIVE so it fires on real lead creation. A person created without a recognized lead source matches no case and is simply not auto-enrolled — a natural gate. Requires the `lead-conversion` playbooks (Cold Outreach / Inbound / Referral / Standard) to exist in this workspace.",
|
|
28
|
+
"triggerType": "event",
|
|
29
|
+
"triggerConfig": {
|
|
30
|
+
"eventPattern": "entity.create.completed",
|
|
31
|
+
"filters": {
|
|
32
|
+
"profileSlug": "person"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"status": "active",
|
|
36
|
+
"metadata": {
|
|
37
|
+
"kind": "lead-conversion-enrollment",
|
|
38
|
+
"pairsWith": "lead-conversion"
|
|
39
|
+
},
|
|
40
|
+
"flowDefinition": {
|
|
41
|
+
"nodes": [
|
|
42
|
+
{
|
|
43
|
+
"id": "trigger",
|
|
44
|
+
"type": "trigger",
|
|
45
|
+
"position": {
|
|
46
|
+
"x": 0,
|
|
47
|
+
"y": 0
|
|
48
|
+
},
|
|
49
|
+
"data": {
|
|
50
|
+
"triggerType": "event",
|
|
51
|
+
"label": "New person created",
|
|
52
|
+
"config": {
|
|
53
|
+
"eventPattern": "entity.create.completed",
|
|
54
|
+
"filters": {
|
|
55
|
+
"profileSlug": "person"
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"id": "read-lead",
|
|
62
|
+
"type": "entity_read",
|
|
63
|
+
"position": {
|
|
64
|
+
"x": 0,
|
|
65
|
+
"y": 120
|
|
66
|
+
},
|
|
67
|
+
"data": {
|
|
68
|
+
"label": "Load the new lead",
|
|
69
|
+
"entityId": "{{trigger.payload.subjectId}}",
|
|
70
|
+
"_note": "The entity.create.completed event data payload is only { profileSlug, title } — it does NOT carry the entity's properties. So the lead's `leadSource` must be READ from the entity here; the switch below matches on this node's output, not on the trigger payload."
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
"id": "route-by-source",
|
|
75
|
+
"type": "switch",
|
|
76
|
+
"position": {
|
|
77
|
+
"x": 0,
|
|
78
|
+
"y": 240
|
|
79
|
+
},
|
|
80
|
+
"data": {
|
|
81
|
+
"label": "Route by lead source",
|
|
82
|
+
"expression": "{{steps.read-lead.output.entity.properties.leadSource}}",
|
|
83
|
+
"cases": [
|
|
84
|
+
{
|
|
85
|
+
"value": "cold-outreach",
|
|
86
|
+
"label": "Cold outreach"
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"value": "linkedin",
|
|
90
|
+
"label": "LinkedIn"
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"value": "landing-page",
|
|
94
|
+
"label": "Landing page"
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
"value": "inbound-call",
|
|
98
|
+
"label": "Inbound call"
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
"value": "referral",
|
|
102
|
+
"label": "Referral"
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"value": "twitter",
|
|
106
|
+
"label": "Twitter / X"
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"value": "event",
|
|
110
|
+
"label": "Event"
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
"value": "other",
|
|
114
|
+
"label": "Other"
|
|
115
|
+
}
|
|
116
|
+
],
|
|
117
|
+
"_note": "The switch has NO default handle: a value that matches no case prunes all outgoing edges (no enrollment). So EVERY leadSource enum value is enumerated as a case; the ones without a tailored overlay (twitter, event, other) route to the Standard playbook. Keep these `value`s in lock-step with the person.leadSource enumValues in crm.yaml."
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
"id": "run-cold-outreach",
|
|
122
|
+
"type": "playbook_run",
|
|
123
|
+
"position": {
|
|
124
|
+
"x": -300,
|
|
125
|
+
"y": 360
|
|
126
|
+
},
|
|
127
|
+
"data": {
|
|
128
|
+
"label": "Enroll → Cold Outreach",
|
|
129
|
+
"playbookName": "Conversion — Cold Outreach",
|
|
130
|
+
"paramsMapping": {
|
|
131
|
+
"subjectId": "{{trigger.payload.subjectId}}"
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
"id": "run-inbound",
|
|
137
|
+
"type": "playbook_run",
|
|
138
|
+
"position": {
|
|
139
|
+
"x": -100,
|
|
140
|
+
"y": 360
|
|
141
|
+
},
|
|
142
|
+
"data": {
|
|
143
|
+
"label": "Enroll → Inbound",
|
|
144
|
+
"playbookName": "Conversion — Inbound",
|
|
145
|
+
"paramsMapping": {
|
|
146
|
+
"subjectId": "{{trigger.payload.subjectId}}"
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
"id": "run-referral",
|
|
152
|
+
"type": "playbook_run",
|
|
153
|
+
"position": {
|
|
154
|
+
"x": 100,
|
|
155
|
+
"y": 360
|
|
156
|
+
},
|
|
157
|
+
"data": {
|
|
158
|
+
"label": "Enroll → Referral",
|
|
159
|
+
"playbookName": "Conversion — Referral",
|
|
160
|
+
"paramsMapping": {
|
|
161
|
+
"subjectId": "{{trigger.payload.subjectId}}"
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
"id": "run-standard",
|
|
167
|
+
"type": "playbook_run",
|
|
168
|
+
"position": {
|
|
169
|
+
"x": 300,
|
|
170
|
+
"y": 360
|
|
171
|
+
},
|
|
172
|
+
"data": {
|
|
173
|
+
"label": "Enroll → Standard (fallback)",
|
|
174
|
+
"playbookName": "Conversion — Standard",
|
|
175
|
+
"paramsMapping": {
|
|
176
|
+
"subjectId": "{{trigger.payload.subjectId}}"
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
],
|
|
181
|
+
"edges": [
|
|
182
|
+
{
|
|
183
|
+
"id": "e-trigger",
|
|
184
|
+
"source": "trigger",
|
|
185
|
+
"target": "read-lead"
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
"id": "e-read",
|
|
189
|
+
"source": "read-lead",
|
|
190
|
+
"target": "route-by-source"
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
"id": "e-cold",
|
|
194
|
+
"source": "route-by-source",
|
|
195
|
+
"target": "run-cold-outreach",
|
|
196
|
+
"sourceHandle": "cold-outreach"
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
"id": "e-linkedin",
|
|
200
|
+
"source": "route-by-source",
|
|
201
|
+
"target": "run-cold-outreach",
|
|
202
|
+
"sourceHandle": "linkedin"
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
"id": "e-landing",
|
|
206
|
+
"source": "route-by-source",
|
|
207
|
+
"target": "run-inbound",
|
|
208
|
+
"sourceHandle": "landing-page"
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
"id": "e-call",
|
|
212
|
+
"source": "route-by-source",
|
|
213
|
+
"target": "run-inbound",
|
|
214
|
+
"sourceHandle": "inbound-call"
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
"id": "e-referral",
|
|
218
|
+
"source": "route-by-source",
|
|
219
|
+
"target": "run-referral",
|
|
220
|
+
"sourceHandle": "referral"
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
"id": "e-twitter",
|
|
224
|
+
"source": "route-by-source",
|
|
225
|
+
"target": "run-standard",
|
|
226
|
+
"sourceHandle": "twitter"
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
"id": "e-event",
|
|
230
|
+
"source": "route-by-source",
|
|
231
|
+
"target": "run-standard",
|
|
232
|
+
"sourceHandle": "event"
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
"id": "e-other",
|
|
236
|
+
"source": "route-by-source",
|
|
237
|
+
"target": "run-standard",
|
|
238
|
+
"sourceHandle": "other"
|
|
239
|
+
}
|
|
240
|
+
]
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
]
|
|
244
|
+
},
|
|
245
|
+
"dependencies": []
|
|
246
|
+
}
|