Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
SYNAPSE_ENV=staging
SYNAPSE_GATEWAY=
SYNAPSE_API_KEY=agt_xxx
SYNAPSE_AGENT_KEY=agt_xxx
38 changes: 30 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,24 @@ SynapseNetwork lets an agent discover services, invoke them through a gateway, a
3. Search, invoke, and read the receipt.

> Public Preview default: SDK examples use `staging`, backed by `https://api-staging.synapse-network.ai`.
> The `prod` preset points to `https://api.synapse-network.ai`, but production should only be used after official DNS and `/health` are live.
> After production launch, replace the public examples and tests with the `prod` environment.

## Choose Your Integration Path

| Goal | Use |
|---|---|
| Connect SynapseNetwork to an agent framework such as Cursor, Claude Desktop, or LangChain | Official MCP server: `@synapse-network/mcp-server` with `SYNAPSE_AGENT_KEY=agt_xxx` |
| Write application code that invokes services directly | This SDK with `SynapseClient` |
| Issue Agent Keys or publish provider APIs | Advanced owner/provider APIs: `SynapseAuth` and `auth.provider()` |

## Two Invocation Modes

| Mode | Use for | SDK method | Required cost parameter | Billing result |
|---|---|---|---|---|
| Fixed-price API invoke | Normal API services discovered from the marketplace | Python `invoke()` / TypeScript `invoke()` | Pass latest discovery price as `cost_usdc` / `costUsdc` | Gateway rejects with `PRICE_MISMATCH` if the live price changed |
| Token-metered LLM invoke | LLM services registered with `serviceKind=llm` and `priceModel=token_metered` | Python `invoke_llm()` / TypeScript `invokeLlm()` | Do not pass `cost_usdc` / `costUsdc`; optional cap is `max_cost_usdc` / `maxCostUsdc` | Gateway holds a cap, then charges final provider-reported token usage |

Do not recompute money with floating-point math. Pass discovered prices and spend caps through exactly; prefer string amounts such as `"0.05"` when the SDK method accepts strings.

## Gateway Docs

Expand All @@ -40,8 +57,6 @@ SynapseNetwork lets an agent discover services, invoke them through a gateway, a
| Environment | Gateway URL | Intended use |
|---|---|---|
| `staging` | `https://api-staging.synapse-network.ai` | Public preview, test assets, integration trials |
| `local` | `http://127.0.0.1:8000` | Local gateway development |
| `prod` | `https://api.synapse-network.ai` | Production preset, pending official DNS and health verification |

Resolution rules:

Expand Down Expand Up @@ -74,7 +89,7 @@ Step 2: let your agent discover and work.
```bash
pip install synapse-client
export SYNAPSE_ENV=staging
export SYNAPSE_API_KEY=agt_xxx
export SYNAPSE_AGENT_KEY=agt_xxx
```

```python
Expand All @@ -88,7 +103,7 @@ service = services[0]
result = client.invoke(
service.service_id,
{"prompt": "hello"},
cost_usdc=float(service.price_usdc),
cost_usdc=str(service.price_usdc),
idempotency_key="agent-job-001",
)

Expand All @@ -113,8 +128,13 @@ npm install @synapse-network/sdk
```ts
import { SynapseClient } from "@synapse-network/sdk";

const agentKey = process.env.SYNAPSE_AGENT_KEY;
if (!agentKey) {
throw new Error("SYNAPSE_AGENT_KEY is required");
}

const client = new SynapseClient({
credential: "agt_xxx",
credential: agentKey,
environment: "staging",
});

Expand All @@ -127,7 +147,7 @@ const result = await client.invoke(
service.serviceId ?? service.id!,
{ prompt: "hello" },
{
costUsdc: Number(service.pricing?.amount ?? 0),
costUsdc: String(service.pricing?.amount ?? "0"),
idempotencyKey: "agent-job-001",
}
);
Expand All @@ -138,6 +158,8 @@ console.log(receipt.invocationId, receipt.status, receipt.chargedUsdc);

TypeScript does not read environment variables by itself. Read them in your app and pass `environment` or `gatewayUrl` explicitly.

Python reads `SYNAPSE_AGENT_KEY` by default. `SYNAPSE_API_KEY` remains a legacy compatibility alias, but new examples should use `SYNAPSE_AGENT_KEY`.

### LLM token-metered calls

LLM services registered with `serviceKind=llm` and `priceModel=token_metered` use `invoke_llm()` / `invokeLlm()`. Do not pass `cost_usdc` / `costUsdc`; pass optional `max_cost_usdc` / `maxCostUsdc` or let Gateway compute the automatic hold. Streaming is rejected in V1 so Gateway can capture final usage safely.
Expand Down Expand Up @@ -267,7 +289,7 @@ PYTHONPATH="$PWD" .venv/bin/python examples/provider_staging_onboarding.py \
Call a provider service with an existing Agent Key:

```bash
export SYNAPSE_API_KEY=agt_xxx
export SYNAPSE_AGENT_KEY=agt_xxx
PYTHONPATH="$PWD" .venv/bin/python examples/consumer_call_provider.py \
--service-id "weather_api" \
--payload-json '{"prompt":"hello"}'
Expand Down
38 changes: 30 additions & 8 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,24 @@ SynapseNetwork 让 Agent 可以发现服务、通过 gateway 调用服务,并
3. 搜索服务、调用服务、读取 receipt。

> Public Preview 默认使用 `staging`,对应 `https://api-staging.synapse-network.ai`。
> `prod` 预设指向 `https://api.synapse-network.ai`,但只有在官方 DNS 和 `/health` 验证通过后才应使用生产环境。
> 生产环境上线后,再把公开示例和测试统一切换到 `prod`。

## 选择你的接入路径

| 目标 | 使用 |
|---|---|
| 把 SynapseNetwork 接入 Cursor、Claude Desktop、LangChain 等 Agent framework | 官方 MCP server:`@synapse-network/mcp-server`,设置 `SYNAPSE_AGENT_KEY=agt_xxx` |
| 在应用代码里直接调用服务 | 本 SDK 的 `SynapseClient` |
| 签发 Agent Key 或发布 Provider API | 高级 owner/provider API:`SynapseAuth` 和 `auth.provider()` |

## 两种调用模式

| 模式 | 适用场景 | SDK 方法 | 必传费用参数 | 计费结果 |
|---|---|---|---|---|
| Fixed-price API invoke | marketplace 发现的普通 API 服务 | Python `invoke()` / TypeScript `invoke()` | 传最新 discovery price:`cost_usdc` / `costUsdc` | 如果 live price 已变化,Gateway 用 `PRICE_MISMATCH` 拒绝 |
| Token-metered LLM invoke | `serviceKind=llm` 且 `priceModel=token_metered` 的 LLM 服务 | Python `invoke_llm()` / TypeScript `invokeLlm()` | 不传 `cost_usdc` / `costUsdc`;可选上限是 `max_cost_usdc` / `maxCostUsdc` | Gateway 先冻结上限,再按 Provider 返回的 final token usage 扣费 |

不要用浮点数重新计算金额。调用时传 discovery 得到的价格或预算上限;SDK 方法支持时优先使用字符串金额,例如 `"0.05"`。

## Gateway 文档

Expand All @@ -40,8 +57,6 @@ SynapseNetwork 让 Agent 可以发现服务、通过 gateway 调用服务,并
| 环境 | Gateway URL | 用途 |
|---|---|---|
| `staging` | `https://api-staging.synapse-network.ai` | Public preview、测试资产和接入试跑 |
| `local` | `http://127.0.0.1:8000` | 本地 gateway 开发 |
| `prod` | `https://api.synapse-network.ai` | 生产预设,等待官方 DNS 和 health 验证 |

解析优先级:

Expand Down Expand Up @@ -74,7 +89,7 @@ Provider 是 owner scope 下的供给侧角色,不是第二套根账户体系
```bash
pip install synapse-client
export SYNAPSE_ENV=staging
export SYNAPSE_API_KEY=agt_xxx
export SYNAPSE_AGENT_KEY=agt_xxx
```

```python
Expand All @@ -88,7 +103,7 @@ service = services[0]
result = client.invoke(
service.service_id,
{"prompt": "hello"},
cost_usdc=float(service.price_usdc),
cost_usdc=str(service.price_usdc),
idempotency_key="agent-job-001",
)

Expand All @@ -113,8 +128,13 @@ npm install @synapse-network/sdk
```ts
import { SynapseClient } from "@synapse-network/sdk";

const agentKey = process.env.SYNAPSE_AGENT_KEY;
if (!agentKey) {
throw new Error("SYNAPSE_AGENT_KEY is required");
}

const client = new SynapseClient({
credential: "agt_xxx",
credential: agentKey,
environment: "staging",
});

Expand All @@ -127,7 +147,7 @@ const result = await client.invoke(
service.serviceId ?? service.id!,
{ prompt: "hello" },
{
costUsdc: Number(service.pricing?.amount ?? 0),
costUsdc: String(service.pricing?.amount ?? "0"),
idempotencyKey: "agent-job-001",
}
);
Expand All @@ -138,6 +158,8 @@ console.log(receipt.invocationId, receipt.status, receipt.chargedUsdc);

TypeScript SDK 不会自动读取环境变量。请在你的应用中读取环境变量,然后显式传入 `environment` 或 `gatewayUrl`。

Python 默认读取 `SYNAPSE_AGENT_KEY`。`SYNAPSE_API_KEY` 只作为 legacy 兼容别名保留,新示例统一使用 `SYNAPSE_AGENT_KEY`。

### LLM 按 token 计费调用

使用 `serviceKind=llm` 和 `priceModel=token_metered` 注册的 LLM 服务,需要调用 `invoke_llm()` / `invokeLlm()`。不要传 `cost_usdc` / `costUsdc`;可以传可选的 `max_cost_usdc` / `maxCostUsdc`,也可以交给 Gateway 自动冻结。V1 会拒绝 streaming,确保 Gateway 能拿到 final usage 后再扣费。
Expand Down Expand Up @@ -267,7 +289,7 @@ PYTHONPATH="$PWD" .venv/bin/python examples/provider_staging_onboarding.py \
使用已有 Agent Key 调用 provider service:

```bash
export SYNAPSE_API_KEY=agt_xxx
export SYNAPSE_AGENT_KEY=agt_xxx
PYTHONPATH="$PWD" .venv/bin/python examples/consumer_call_provider.py \
--service-id "weather_api" \
--payload-json '{"prompt":"hello"}'
Expand Down
2 changes: 1 addition & 1 deletion docs/agent-map/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ Domain 摘要。
| `sdk_runtime_client` | discovery, invoke, receipt, usage, runtime errors |
| `sdk_owner_auth` | wallet auth, credential issue/list/status/quota, owner control plane |
| `sdk_provider_lifecycle` | provider facade, provider secrets, service registration, service lifecycle, provider health |
| `sdk_environment_config` | staging/prod/local presets, gateway URL resolution, public preview defaults |
| `sdk_environment_config` | staging defaults, future prod switch, gateway URL resolution, public preview defaults |
| `sdk_public_docs` | README, integration guides, capability inventory, examples |
| `sdk_ci_quality_gates` | GitHub Actions, shell CI scripts, coverage gates |
| `sdk_examples_and_e2e` | examples, smoke tests, onboarding e2e plans |
Expand Down
11 changes: 7 additions & 4 deletions docs/agent-map/index.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@
"bash scripts/ci/typescript_checks.sh"
],
"notes": [
"Canonical runtime flow is discovery/search plus price-asserted invoke plus receipt.",
"Canonical runtime flow is discovery/search plus one of two invoke modes: fixed-price invoke with costUsdc/cost_usdc, or token-metered LLM invoke with maxCostUsdc/max_cost_usdc.",
"Public examples should use SYNAPSE_AGENT_KEY for agent runtime credentials; SYNAPSE_API_KEY is only a Python legacy fallback.",
"Do not restore old quote-first gateway calls."
]
},
Expand Down Expand Up @@ -108,7 +109,7 @@
"id": "sdk_environment_config",
"title": "Gateway environment configuration",
"use_when": [
"local, staging, prod, gateway URL, environment resolver, or public preview defaults change",
"staging, future prod, gateway URL, environment resolver, or public preview defaults change",
"README or SECURITY guidance for staging/prod changes"
],
"primary_files": [
Expand All @@ -132,6 +133,7 @@
],
"notes": [
"Default environment is staging.",
"Do not reintroduce removed non-staging gateway presets or gateway setup docs.",
"Do not reintroduce the retired gateway domain from the old .network namespace.",
"Explicit gateway URL always wins over environment preset."
]
Expand Down Expand Up @@ -167,7 +169,8 @@
"notes": [
"Public docs should say Public Preview unless production DNS and health checks are verified.",
"Use agt_xxx or REPLACE_ME placeholders only.",
"README and gateway docs must show Agent Key -> SynapseClient first, with owner auth -> JWT -> credential issuance under Advanced."
"README and gateway docs must show SYNAPSE_AGENT_KEY -> SynapseClient first, with owner auth -> JWT -> credential issuance under Advanced.",
"README and gateway docs must explain fixed-price API invoke versus token-metered LLM invoke before advanced owner/provider flows."
]
},
{
Expand Down Expand Up @@ -226,7 +229,7 @@
"bash scripts/ci/typescript_checks.sh"
],
"notes": [
"Provider staging examples require a public HTTPS endpoint, not localhost.",
"Provider staging examples require a public HTTPS endpoint reachable by the staging gateway.",
"Consumer wallet-to-invoke examples default to free services unless --allow-paid is explicit.",
"E2E flows may require real staging credentials; PR CI should keep e2e out of the default gate unless explicitly configured."
]
Expand Down
Loading
Loading