@synapsor/runner 0.1.9 → 0.1.11
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/CHANGELOG.md +32 -0
- package/README.md +60 -29
- package/dist/cli.d.ts.map +1 -1
- package/dist/runner.mjs +719 -47
- package/docs/README.md +6 -0
- package/docs/cloud-mode.md +18 -0
- package/docs/cloud-push.md +54 -0
- package/docs/current-scope.md +1 -1
- package/docs/local-mode.md +4 -3
- package/docs/mcp-clients.md +123 -0
- package/docs/release-notes.md +30 -0
- package/docs/runner-bundles.md +59 -0
- package/examples/support-plan-credit/.env.example +10 -0
- package/examples/support-plan-credit/README.md +273 -0
- package/examples/support-plan-credit/contract.synapsor +59 -0
- package/examples/support-plan-credit/docker-compose.yml +12 -0
- package/examples/support-plan-credit/expected-output/cloud-push-response.json +9 -0
- package/examples/support-plan-credit/expected-output/proposal-created.json +23 -0
- package/examples/support-plan-credit/expected-output/receipt.json +13 -0
- package/examples/support-plan-credit/expected-output/replay-summary.json +13 -0
- package/examples/support-plan-credit/expected-output/tools-preview.txt +15 -0
- package/examples/support-plan-credit/mcp-client-examples/claude-desktop.json +20 -0
- package/examples/support-plan-credit/mcp-client-examples/cursor-global.mcp.json +20 -0
- package/examples/support-plan-credit/mcp-client-examples/cursor-project.mcp.json +20 -0
- package/examples/support-plan-credit/mcp-client-examples/generic-stdio.json +17 -0
- package/examples/support-plan-credit/mcp-client-examples/generic-streamable-http.json +5 -0
- package/examples/support-plan-credit/mcp-client-examples/openai-agents-stdio.ts +19 -0
- package/examples/support-plan-credit/mcp-client-examples/openai-agents-streamable-http.ts +20 -0
- package/examples/support-plan-credit/seed/001_seed.sql +92 -0
- package/examples/support-plan-credit/synapsor.contract.json +198 -0
- package/examples/support-plan-credit/synapsor.runner.json +18 -0
- package/package.json +2 -1
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
CREATE AGENT CONTEXT support_agent_context
|
|
2
|
+
BIND tenant_id FROM ENVIRONMENT SYNAPSOR_TENANT_ID REQUIRED
|
|
3
|
+
BIND principal FROM ENVIRONMENT SYNAPSOR_PRINCIPAL REQUIRED
|
|
4
|
+
TENANT BINDING tenant_id
|
|
5
|
+
PRINCIPAL BINDING principal
|
|
6
|
+
END
|
|
7
|
+
|
|
8
|
+
CREATE CAPABILITY support.inspect_customer
|
|
9
|
+
DESCRIPTION 'Inspect one support customer in the trusted tenant before proposing a plan credit.'
|
|
10
|
+
RETURNS HINT 'Returns reviewed customer fields plus evidence/query-audit handles.'
|
|
11
|
+
USING CONTEXT support_agent_context
|
|
12
|
+
SOURCE local_postgres
|
|
13
|
+
ON public.customers
|
|
14
|
+
PRIMARY KEY id
|
|
15
|
+
TENANT KEY tenant_id
|
|
16
|
+
CONFLICT GUARD updated_at
|
|
17
|
+
LOOKUP customer_id BY id
|
|
18
|
+
ARG customer_id STRING REQUIRED MAX LENGTH 128 DESCRIPTION 'Customer id such as CUS-3001.'
|
|
19
|
+
ALLOW READ id, tenant_id, customer_id, plan, invoice_status, support_ticket_reason, plan_credit_cents, credit_reason, updated_at
|
|
20
|
+
KEEP OUT card_token, raw_payment_method, internal_risk_score, private_notes
|
|
21
|
+
REQUIRE EVIDENCE
|
|
22
|
+
MAX ROWS 1
|
|
23
|
+
END
|
|
24
|
+
|
|
25
|
+
CREATE CAPABILITY support.propose_plan_credit
|
|
26
|
+
DESCRIPTION 'Propose a bounded support plan credit after inspecting customer and ticket evidence.'
|
|
27
|
+
RETURNS HINT 'Returns a proposal id, exact diff, evidence handle, and source_database_changed:false. Policy may approve small credits, but writeback is still separate.'
|
|
28
|
+
USING CONTEXT support_agent_context
|
|
29
|
+
SOURCE local_postgres
|
|
30
|
+
ON public.customers
|
|
31
|
+
PRIMARY KEY id
|
|
32
|
+
TENANT KEY tenant_id
|
|
33
|
+
CONFLICT GUARD updated_at
|
|
34
|
+
LOOKUP customer_id BY id
|
|
35
|
+
ARG customer_id STRING REQUIRED MAX LENGTH 128 DESCRIPTION 'Customer id such as CUS-3001.'
|
|
36
|
+
ARG credit_cents NUMBER REQUIRED MIN 1 DESCRIPTION 'Requested plan credit in cents.'
|
|
37
|
+
ARG reason TEXT REQUIRED MAX LENGTH 500 DESCRIPTION 'Business reason tied to support evidence.'
|
|
38
|
+
ALLOW READ id, tenant_id, customer_id, plan, invoice_status, support_ticket_reason, plan_credit_cents, credit_reason, updated_at
|
|
39
|
+
KEEP OUT card_token, raw_payment_method, internal_risk_score, private_notes
|
|
40
|
+
REQUIRE EVIDENCE
|
|
41
|
+
MAX ROWS 1
|
|
42
|
+
PROPOSE ACTION grant_plan_credit
|
|
43
|
+
ALLOW WRITE plan_credit_cents, credit_reason
|
|
44
|
+
PATCH plan_credit_cents = ARG credit_cents
|
|
45
|
+
PATCH credit_reason = ARG reason
|
|
46
|
+
BOUND plan_credit_cents 1..50000
|
|
47
|
+
APPROVAL ROLE support_reviewer
|
|
48
|
+
AUTO APPROVE WHEN plan_credit_cents <= 2500
|
|
49
|
+
WRITEBACK DIRECT SQL
|
|
50
|
+
END
|
|
51
|
+
|
|
52
|
+
CREATE AGENT WORKFLOW support.plan_credit_request
|
|
53
|
+
USING CONTEXT support_agent_context
|
|
54
|
+
ALLOW CAPABILITY support.inspect_customer
|
|
55
|
+
ALLOW CAPABILITY support.propose_plan_credit
|
|
56
|
+
REQUIRE EVIDENCE
|
|
57
|
+
APPROVAL REQUIRED ROLE support_reviewer
|
|
58
|
+
CHECKPOINT PROPOSAL ONLY
|
|
59
|
+
END
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
services:
|
|
2
|
+
postgres:
|
|
3
|
+
image: postgres:16
|
|
4
|
+
container_name: synapsor_runner_plan_credit
|
|
5
|
+
environment:
|
|
6
|
+
POSTGRES_DB: synapsor_runner_plan_credit
|
|
7
|
+
POSTGRES_USER: synapsor_admin
|
|
8
|
+
POSTGRES_PASSWORD: synapsor_admin_password
|
|
9
|
+
ports:
|
|
10
|
+
- "55438:5432"
|
|
11
|
+
volumes:
|
|
12
|
+
- ./seed:/docker-entrypoint-initdb.d:ro
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
{
|
|
2
|
+
"ok": true,
|
|
3
|
+
"contract_id": "act_support_plan_credit_example",
|
|
4
|
+
"contract_version_id": "act_support_plan_credit_example_v1",
|
|
5
|
+
"version_number": 1,
|
|
6
|
+
"status": "draft",
|
|
7
|
+
"digest": "sha256:<server-computed-digest>",
|
|
8
|
+
"registry_url": "/workspace/contracts?contract=<contract_id>"
|
|
9
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"proposal_id": "wrp_example_low_risk_credit",
|
|
3
|
+
"capability": "support.propose_plan_credit",
|
|
4
|
+
"status": "approved",
|
|
5
|
+
"approval_actor": "policy:support_propose_plan_credit_auto_approval",
|
|
6
|
+
"target": {
|
|
7
|
+
"table": "customers",
|
|
8
|
+
"id": "CUS-3001",
|
|
9
|
+
"tenant_id": "acme"
|
|
10
|
+
},
|
|
11
|
+
"change_set": {
|
|
12
|
+
"plan_credit_cents": {
|
|
13
|
+
"before": 0,
|
|
14
|
+
"after": 2500
|
|
15
|
+
},
|
|
16
|
+
"credit_reason": {
|
|
17
|
+
"before": null,
|
|
18
|
+
"after": "SLA outage ticket SUP-481"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"source_database_changed": false,
|
|
22
|
+
"evidence_handle": "evidence://local/example-plan-credit"
|
|
23
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"receipt_id": "rct_example_plan_credit",
|
|
3
|
+
"proposal_id": "wrp_example_low_risk_credit",
|
|
4
|
+
"status": "applied",
|
|
5
|
+
"rows_affected": 1,
|
|
6
|
+
"guards": {
|
|
7
|
+
"tenant": "passed",
|
|
8
|
+
"primary_key": "passed",
|
|
9
|
+
"allowed_columns": "passed",
|
|
10
|
+
"expected_version": "passed",
|
|
11
|
+
"idempotency": "passed"
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"proposal_id": "wrp_example_low_risk_credit",
|
|
3
|
+
"events": [
|
|
4
|
+
"scoped_read",
|
|
5
|
+
"evidence_saved",
|
|
6
|
+
"proposal_created",
|
|
7
|
+
"policy_approved",
|
|
8
|
+
"guarded_writeback_applied",
|
|
9
|
+
"receipt_recorded"
|
|
10
|
+
],
|
|
11
|
+
"source_database_changed_before_approval": false,
|
|
12
|
+
"final_status": "applied"
|
|
13
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
Synapsor tools preview: ok
|
|
2
|
+
|
|
3
|
+
Exposed to MCP:
|
|
4
|
+
- support.inspect_customer
|
|
5
|
+
- support.propose_plan_credit
|
|
6
|
+
|
|
7
|
+
Not exposed to MCP:
|
|
8
|
+
- execute_sql / raw query tools
|
|
9
|
+
- approval tools
|
|
10
|
+
- commit/apply tools
|
|
11
|
+
- database URLs
|
|
12
|
+
- write credentials
|
|
13
|
+
- model-controlled tenant authority
|
|
14
|
+
|
|
15
|
+
auto-approval: enabled
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"mcpServers": {
|
|
3
|
+
"synapsor-runner": {
|
|
4
|
+
"command": "npx",
|
|
5
|
+
"args": [
|
|
6
|
+
"-y",
|
|
7
|
+
"-p",
|
|
8
|
+
"@synapsor/runner",
|
|
9
|
+
"synapsor-runner",
|
|
10
|
+
"mcp",
|
|
11
|
+
"serve",
|
|
12
|
+
"--config",
|
|
13
|
+
"examples/support-plan-credit/synapsor.runner.json",
|
|
14
|
+
"--store",
|
|
15
|
+
"./tmp/support-plan-credit/local.db"
|
|
16
|
+
],
|
|
17
|
+
"cwd": "<absolute-path-to-Synapsor-Runner>"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"mcpServers": {
|
|
3
|
+
"synapsor-runner": {
|
|
4
|
+
"type": "stdio",
|
|
5
|
+
"command": "npx",
|
|
6
|
+
"args": [
|
|
7
|
+
"-y",
|
|
8
|
+
"-p",
|
|
9
|
+
"@synapsor/runner",
|
|
10
|
+
"synapsor-runner",
|
|
11
|
+
"mcp",
|
|
12
|
+
"serve",
|
|
13
|
+
"--config",
|
|
14
|
+
"<absolute-path-to-Synapsor-Runner>/examples/support-plan-credit/synapsor.runner.json",
|
|
15
|
+
"--store",
|
|
16
|
+
"<absolute-path-to-Synapsor-Runner>/tmp/support-plan-credit/local.db"
|
|
17
|
+
]
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"mcpServers": {
|
|
3
|
+
"synapsor-runner": {
|
|
4
|
+
"type": "stdio",
|
|
5
|
+
"command": "npx",
|
|
6
|
+
"args": [
|
|
7
|
+
"-y",
|
|
8
|
+
"-p",
|
|
9
|
+
"@synapsor/runner",
|
|
10
|
+
"synapsor-runner",
|
|
11
|
+
"mcp",
|
|
12
|
+
"serve",
|
|
13
|
+
"--config",
|
|
14
|
+
"examples/support-plan-credit/synapsor.runner.json",
|
|
15
|
+
"--store",
|
|
16
|
+
"./tmp/support-plan-credit/local.db"
|
|
17
|
+
]
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "synapsor-runner",
|
|
3
|
+
"transport": "stdio",
|
|
4
|
+
"command": "npx",
|
|
5
|
+
"args": [
|
|
6
|
+
"-y",
|
|
7
|
+
"-p",
|
|
8
|
+
"@synapsor/runner",
|
|
9
|
+
"synapsor-runner",
|
|
10
|
+
"mcp",
|
|
11
|
+
"serve",
|
|
12
|
+
"--config",
|
|
13
|
+
"examples/support-plan-credit/synapsor.runner.json",
|
|
14
|
+
"--store",
|
|
15
|
+
"./tmp/support-plan-credit/local.db"
|
|
16
|
+
]
|
|
17
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Agent, MCPServerStdio, run } from "@openai/agents";
|
|
2
|
+
|
|
3
|
+
const synapsor = new MCPServerStdio({
|
|
4
|
+
name: "Synapsor Runner",
|
|
5
|
+
fullCommand: "npx -y -p @synapsor/runner synapsor-runner mcp serve --config examples/support-plan-credit/synapsor.runner.json --store ./tmp/support-plan-credit/local.db --alias-mode openai",
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
await synapsor.connect();
|
|
9
|
+
try {
|
|
10
|
+
const agent = new Agent({
|
|
11
|
+
name: "Support operations agent",
|
|
12
|
+
instructions: "Use only Synapsor business tools. Inspect evidence before proposing a plan credit.",
|
|
13
|
+
mcpServers: [synapsor],
|
|
14
|
+
});
|
|
15
|
+
const result = await run(agent, "Inspect customer CUS-3001 and propose a $25 plan credit for SLA outage ticket SUP-481.");
|
|
16
|
+
console.log(result.finalOutput);
|
|
17
|
+
} finally {
|
|
18
|
+
await synapsor.close();
|
|
19
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Agent, MCPServerStreamableHttp, run } from "@openai/agents";
|
|
2
|
+
|
|
3
|
+
// Start Runner with --alias-mode openai so model-visible tool names are valid OpenAI function names.
|
|
4
|
+
const synapsor = new MCPServerStreamableHttp({
|
|
5
|
+
name: "Synapsor Runner",
|
|
6
|
+
url: "http://127.0.0.1:8766/mcp",
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
await synapsor.connect();
|
|
10
|
+
try {
|
|
11
|
+
const agent = new Agent({
|
|
12
|
+
name: "Support operations agent",
|
|
13
|
+
instructions: "Use only Synapsor business tools. Inspect evidence before proposing a plan credit.",
|
|
14
|
+
mcpServers: [synapsor],
|
|
15
|
+
});
|
|
16
|
+
const result = await run(agent, "Inspect customer CUS-3001 and propose a $25 plan credit for SLA outage ticket SUP-481.");
|
|
17
|
+
console.log(result.finalOutput);
|
|
18
|
+
} finally {
|
|
19
|
+
await synapsor.close();
|
|
20
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
CREATE TABLE IF NOT EXISTS public.customers (
|
|
2
|
+
id text PRIMARY KEY,
|
|
3
|
+
tenant_id text NOT NULL,
|
|
4
|
+
customer_id text NOT NULL,
|
|
5
|
+
plan text NOT NULL,
|
|
6
|
+
invoice_status text NOT NULL,
|
|
7
|
+
support_ticket_reason text NOT NULL,
|
|
8
|
+
plan_credit_cents integer NOT NULL DEFAULT 0,
|
|
9
|
+
credit_reason text,
|
|
10
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
11
|
+
card_token text,
|
|
12
|
+
raw_payment_method text,
|
|
13
|
+
internal_risk_score integer,
|
|
14
|
+
private_notes text
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
INSERT INTO public.customers (
|
|
18
|
+
id,
|
|
19
|
+
tenant_id,
|
|
20
|
+
customer_id,
|
|
21
|
+
plan,
|
|
22
|
+
invoice_status,
|
|
23
|
+
support_ticket_reason,
|
|
24
|
+
plan_credit_cents,
|
|
25
|
+
credit_reason,
|
|
26
|
+
updated_at,
|
|
27
|
+
card_token,
|
|
28
|
+
raw_payment_method,
|
|
29
|
+
internal_risk_score,
|
|
30
|
+
private_notes
|
|
31
|
+
)
|
|
32
|
+
VALUES
|
|
33
|
+
(
|
|
34
|
+
'CUS-3001',
|
|
35
|
+
'acme',
|
|
36
|
+
'CUS-3001',
|
|
37
|
+
'enterprise',
|
|
38
|
+
'open_dispute',
|
|
39
|
+
'SLA outage ticket SUP-481 confirmed by support lead',
|
|
40
|
+
0,
|
|
41
|
+
NULL,
|
|
42
|
+
'2026-06-20T14:31:08Z',
|
|
43
|
+
'tok_fake_acme_3001',
|
|
44
|
+
'fake_visa_4242',
|
|
45
|
+
12,
|
|
46
|
+
'fake internal note: do not expose'
|
|
47
|
+
),
|
|
48
|
+
(
|
|
49
|
+
'CUS-9001',
|
|
50
|
+
'otherco',
|
|
51
|
+
'CUS-9001',
|
|
52
|
+
'starter',
|
|
53
|
+
'paid',
|
|
54
|
+
'OtherCo tenant row for spoof checks',
|
|
55
|
+
0,
|
|
56
|
+
NULL,
|
|
57
|
+
'2026-06-20T14:31:08Z',
|
|
58
|
+
'tok_fake_otherco_9001',
|
|
59
|
+
'fake_mastercard_4444',
|
|
60
|
+
77,
|
|
61
|
+
'fake other tenant note'
|
|
62
|
+
)
|
|
63
|
+
ON CONFLICT (id) DO UPDATE SET
|
|
64
|
+
tenant_id = EXCLUDED.tenant_id,
|
|
65
|
+
customer_id = EXCLUDED.customer_id,
|
|
66
|
+
plan = EXCLUDED.plan,
|
|
67
|
+
invoice_status = EXCLUDED.invoice_status,
|
|
68
|
+
support_ticket_reason = EXCLUDED.support_ticket_reason,
|
|
69
|
+
plan_credit_cents = EXCLUDED.plan_credit_cents,
|
|
70
|
+
credit_reason = EXCLUDED.credit_reason,
|
|
71
|
+
updated_at = EXCLUDED.updated_at,
|
|
72
|
+
card_token = EXCLUDED.card_token,
|
|
73
|
+
raw_payment_method = EXCLUDED.raw_payment_method,
|
|
74
|
+
internal_risk_score = EXCLUDED.internal_risk_score,
|
|
75
|
+
private_notes = EXCLUDED.private_notes;
|
|
76
|
+
|
|
77
|
+
DO $$
|
|
78
|
+
BEGIN
|
|
79
|
+
IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'synapsor_reader') THEN
|
|
80
|
+
CREATE ROLE synapsor_reader LOGIN PASSWORD 'synapsor_reader_password';
|
|
81
|
+
END IF;
|
|
82
|
+
IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'synapsor_writer') THEN
|
|
83
|
+
CREATE ROLE synapsor_writer LOGIN PASSWORD 'synapsor_writer_password';
|
|
84
|
+
END IF;
|
|
85
|
+
END
|
|
86
|
+
$$;
|
|
87
|
+
|
|
88
|
+
GRANT CONNECT ON DATABASE synapsor_runner_plan_credit TO synapsor_reader, synapsor_writer;
|
|
89
|
+
GRANT USAGE ON SCHEMA public TO synapsor_reader, synapsor_writer;
|
|
90
|
+
GRANT CREATE ON SCHEMA public TO synapsor_writer;
|
|
91
|
+
GRANT SELECT ON public.customers TO synapsor_reader, synapsor_writer;
|
|
92
|
+
GRANT UPDATE (plan_credit_cents, credit_reason, updated_at) ON public.customers TO synapsor_writer;
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
{
|
|
2
|
+
"capabilities": [
|
|
3
|
+
{
|
|
4
|
+
"args": {
|
|
5
|
+
"customer_id": {
|
|
6
|
+
"description": "Customer id such as CUS-3001.",
|
|
7
|
+
"max_length": 128,
|
|
8
|
+
"required": true,
|
|
9
|
+
"type": "string"
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
"context": "support_agent_context",
|
|
13
|
+
"description": "Inspect one support customer in the trusted tenant before proposing a plan credit.",
|
|
14
|
+
"evidence": {
|
|
15
|
+
"query_audit": true,
|
|
16
|
+
"required": true
|
|
17
|
+
},
|
|
18
|
+
"kept_out_fields": [
|
|
19
|
+
"card_token",
|
|
20
|
+
"raw_payment_method",
|
|
21
|
+
"internal_risk_score",
|
|
22
|
+
"private_notes"
|
|
23
|
+
],
|
|
24
|
+
"kind": "read",
|
|
25
|
+
"lookup": {
|
|
26
|
+
"id_from_arg": "customer_id"
|
|
27
|
+
},
|
|
28
|
+
"max_rows": 1,
|
|
29
|
+
"name": "support.inspect_customer",
|
|
30
|
+
"returns_hint": "Returns reviewed customer fields plus evidence/query-audit handles.",
|
|
31
|
+
"source": "local_postgres",
|
|
32
|
+
"subject": {
|
|
33
|
+
"conflict_key": "updated_at",
|
|
34
|
+
"primary_key": "id",
|
|
35
|
+
"schema": "public",
|
|
36
|
+
"table": "customers",
|
|
37
|
+
"tenant_key": "tenant_id"
|
|
38
|
+
},
|
|
39
|
+
"visible_fields": [
|
|
40
|
+
"id",
|
|
41
|
+
"tenant_id",
|
|
42
|
+
"customer_id",
|
|
43
|
+
"plan",
|
|
44
|
+
"invoice_status",
|
|
45
|
+
"support_ticket_reason",
|
|
46
|
+
"plan_credit_cents",
|
|
47
|
+
"credit_reason",
|
|
48
|
+
"updated_at"
|
|
49
|
+
]
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"args": {
|
|
53
|
+
"credit_cents": {
|
|
54
|
+
"description": "Requested plan credit in cents.",
|
|
55
|
+
"minimum": 1,
|
|
56
|
+
"required": true,
|
|
57
|
+
"type": "number"
|
|
58
|
+
},
|
|
59
|
+
"customer_id": {
|
|
60
|
+
"description": "Customer id such as CUS-3001.",
|
|
61
|
+
"max_length": 128,
|
|
62
|
+
"required": true,
|
|
63
|
+
"type": "string"
|
|
64
|
+
},
|
|
65
|
+
"reason": {
|
|
66
|
+
"description": "Business reason tied to support evidence.",
|
|
67
|
+
"max_length": 500,
|
|
68
|
+
"required": true,
|
|
69
|
+
"type": "string"
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
"context": "support_agent_context",
|
|
73
|
+
"description": "Propose a bounded support plan credit after inspecting customer and ticket evidence.",
|
|
74
|
+
"evidence": {
|
|
75
|
+
"query_audit": true,
|
|
76
|
+
"required": true
|
|
77
|
+
},
|
|
78
|
+
"kept_out_fields": [
|
|
79
|
+
"card_token",
|
|
80
|
+
"raw_payment_method",
|
|
81
|
+
"internal_risk_score",
|
|
82
|
+
"private_notes"
|
|
83
|
+
],
|
|
84
|
+
"kind": "proposal",
|
|
85
|
+
"lookup": {
|
|
86
|
+
"id_from_arg": "customer_id"
|
|
87
|
+
},
|
|
88
|
+
"max_rows": 1,
|
|
89
|
+
"name": "support.propose_plan_credit",
|
|
90
|
+
"proposal": {
|
|
91
|
+
"action": "grant_plan_credit",
|
|
92
|
+
"allowed_fields": [
|
|
93
|
+
"plan_credit_cents",
|
|
94
|
+
"credit_reason"
|
|
95
|
+
],
|
|
96
|
+
"approval": {
|
|
97
|
+
"mode": "policy",
|
|
98
|
+
"policy": "support_propose_plan_credit_auto_approval",
|
|
99
|
+
"required_role": "support_reviewer"
|
|
100
|
+
},
|
|
101
|
+
"conflict_guard": {
|
|
102
|
+
"column": "updated_at"
|
|
103
|
+
},
|
|
104
|
+
"numeric_bounds": {
|
|
105
|
+
"plan_credit_cents": {
|
|
106
|
+
"maximum": 50000,
|
|
107
|
+
"minimum": 1
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
"patch": {
|
|
111
|
+
"credit_reason": {
|
|
112
|
+
"from_arg": "reason"
|
|
113
|
+
},
|
|
114
|
+
"plan_credit_cents": {
|
|
115
|
+
"from_arg": "credit_cents"
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
"writeback": {
|
|
119
|
+
"mode": "direct_sql"
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
"returns_hint": "Returns a proposal id, exact diff, evidence handle, and source_database_changed:false. Policy may approve small credits, but writeback is still separate.",
|
|
123
|
+
"source": "local_postgres",
|
|
124
|
+
"subject": {
|
|
125
|
+
"conflict_key": "updated_at",
|
|
126
|
+
"primary_key": "id",
|
|
127
|
+
"schema": "public",
|
|
128
|
+
"table": "customers",
|
|
129
|
+
"tenant_key": "tenant_id"
|
|
130
|
+
},
|
|
131
|
+
"visible_fields": [
|
|
132
|
+
"id",
|
|
133
|
+
"tenant_id",
|
|
134
|
+
"customer_id",
|
|
135
|
+
"plan",
|
|
136
|
+
"invoice_status",
|
|
137
|
+
"support_ticket_reason",
|
|
138
|
+
"plan_credit_cents",
|
|
139
|
+
"credit_reason",
|
|
140
|
+
"updated_at"
|
|
141
|
+
]
|
|
142
|
+
}
|
|
143
|
+
],
|
|
144
|
+
"contexts": [
|
|
145
|
+
{
|
|
146
|
+
"bindings": [
|
|
147
|
+
{
|
|
148
|
+
"key": "SYNAPSOR_TENANT_ID",
|
|
149
|
+
"name": "tenant_id",
|
|
150
|
+
"required": true,
|
|
151
|
+
"source": "environment"
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
"key": "SYNAPSOR_PRINCIPAL",
|
|
155
|
+
"name": "principal",
|
|
156
|
+
"required": true,
|
|
157
|
+
"source": "environment"
|
|
158
|
+
}
|
|
159
|
+
],
|
|
160
|
+
"name": "support_agent_context",
|
|
161
|
+
"principal_binding": "principal",
|
|
162
|
+
"tenant_binding": "tenant_id"
|
|
163
|
+
}
|
|
164
|
+
],
|
|
165
|
+
"kind": "SynapsorContract",
|
|
166
|
+
"policies": [
|
|
167
|
+
{
|
|
168
|
+
"kind": "approval",
|
|
169
|
+
"mode": "green",
|
|
170
|
+
"name": "support_propose_plan_credit_auto_approval",
|
|
171
|
+
"rules": [
|
|
172
|
+
{
|
|
173
|
+
"field": "plan_credit_cents",
|
|
174
|
+
"max": 2500
|
|
175
|
+
}
|
|
176
|
+
]
|
|
177
|
+
}
|
|
178
|
+
],
|
|
179
|
+
"spec_version": "0.1",
|
|
180
|
+
"workflows": [
|
|
181
|
+
{
|
|
182
|
+
"allowed_capabilities": [
|
|
183
|
+
"support.inspect_customer",
|
|
184
|
+
"support.propose_plan_credit"
|
|
185
|
+
],
|
|
186
|
+
"approval": {
|
|
187
|
+
"required": true,
|
|
188
|
+
"role": "support_reviewer"
|
|
189
|
+
},
|
|
190
|
+
"context": "support_agent_context",
|
|
191
|
+
"name": "support.plan_credit_request",
|
|
192
|
+
"replay": {
|
|
193
|
+
"checkpoint": "proposal_only"
|
|
194
|
+
},
|
|
195
|
+
"required_evidence": true
|
|
196
|
+
}
|
|
197
|
+
]
|
|
198
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"mode": "review",
|
|
4
|
+
"storage": {
|
|
5
|
+
"sqlite_path": "./tmp/support-plan-credit/local.db"
|
|
6
|
+
},
|
|
7
|
+
"contracts": [
|
|
8
|
+
"./synapsor.contract.json"
|
|
9
|
+
],
|
|
10
|
+
"sources": {
|
|
11
|
+
"local_postgres": {
|
|
12
|
+
"engine": "postgres",
|
|
13
|
+
"read_url_env": "PLAN_CREDIT_POSTGRES_READ_URL",
|
|
14
|
+
"write_url_env": "PLAN_CREDIT_POSTGRES_WRITE_URL",
|
|
15
|
+
"statement_timeout_ms": 3000
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@synapsor/runner",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.11",
|
|
4
4
|
"description": "Stop giving AI agents execute_sql; expose reviewed Postgres/MySQL MCP actions with proposals, approval, writeback, and replay.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
"examples/openai-agents-stdio/**",
|
|
26
26
|
"examples/raw-sql-vs-synapsor/**",
|
|
27
27
|
"examples/reference-support-billing-app/**",
|
|
28
|
+
"examples/support-plan-credit/**",
|
|
28
29
|
"examples/support-billing-agent/**",
|
|
29
30
|
"fixtures/**",
|
|
30
31
|
"schemas/**",
|