> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kontext.so/llms.txt
> Use this file to discover all available pages before exploring further.

# API 参考

> Kotlin SDK 暴露的全部类型与方法。

## `KontextAds.createSession(...)`

```kotlin theme={null}
public fun createSession(context: Context, options: SessionOptions): Session
```

按给定的 `SessionOptions` 创建并返回一个新的 `Session`，并在后台触发 `/init`。请传入 `context.applicationContext`，避免 session 与单个 Activity 绑定。

## `SessionOptions`

<ParamField path="publisherToken" type="String" required>
  你的发布方 token。
</ParamField>

<ParamField path="userId" type="String" required>
  终端用户的稳定标识，用于个性化、频次控制与激励视频。
</ParamField>

<ParamField path="conversationId" type="String" required>
  当前对话 / 会话的唯一 ID。
</ParamField>

<ParamField path="enabledPlacementCodes" type="List<String>?" optional>
  请求广告的 placement code 列表。为 null 或空列表时默认 `["inlineAd"]`。
</ParamField>

<ParamField path="adServerUrl" type="String?" optional>
  广告服务器基础 URL 的覆盖。保持 null 即使用 Kontext 的生产环境。
</ParamField>

<ParamField path="character" type="Character?" optional>
  用于内容定向的 AI 角色信息。

  <Expandable title="属性">
    <ParamField path="id" type="String" required />

    <ParamField path="name" type="String" required />

    <ParamField path="avatarUrl" type="URI" required>`java.net.URI` 类型——请用 `URI.create("…")` 构造，不能直接传 `String`。</ParamField>

    <ParamField path="greeting" type="String?" optional />

    <ParamField path="persona" type="String?" optional />

    <ParamField path="tags" type="List<String>?" optional />

    <ParamField path="isNsfw" type="Boolean?" optional />
  </Expandable>
</ParamField>

<ParamField path="variantId" type="String?" optional>
  发布方自定义的用户分组标识（用于 A/B 测试等）。
</ParamField>

<ParamField path="regulatory" type="Regulatory?" optional>
  隐私 / 同意信号。如果你接入了符合 TCF 的 CMP，SDK 会自动收集 TCF（`gdpr` / `gdprConsent`）——仅在需要传 COPPA、GPP 或 US Privacy 时手动设置。

  <Expandable title="属性">
    <ParamField path="gdpr" type="Int?" optional>0、1 或 null。</ParamField>
    <ParamField path="gdprConsent" type="String?" optional>IAB TCF v2 同意串。</ParamField>
    <ParamField path="coppa" type="Int?" optional>0、1 或 null。</ParamField>
    <ParamField path="gpp" type="String?" optional>Global Privacy Platform 串。</ParamField>
    <ParamField path="gppSid" type="List<Int>?" optional>当前请求适用的 GPP section ID 列表。</ParamField>
    <ParamField path="usPrivacy" type="String?" optional>CCPA / LSPA 信号串。</ParamField>
  </Expandable>
</ParamField>

<ParamField path="userEmail" type="String?" optional>
  用于跨设备频次去重的终端用户邮箱。
</ParamField>

<ParamField path="advertisingId" type="String?" optional>
  你自行采集的 GAID。优先级高于 SDK 的自动收集。
</ParamField>

<ParamField path="onEvent" type="(AdEvent) -> Unit" optional>
  每次广告生命周期事件的回调。会在主线程上调用。
</ParamField>

<ParamField path="onDebugEvent" type="(String, Any?) -> Unit" optional>
  可选的诊断事件流——内部所有 SDK 事件（preload 开始/结束、iframe 生命周期、几何更新等）都会触发。集成期间很有用，生产环境可保持为 null。
</ParamField>

## `Session`

<ParamField path="addMessage(message, options)" type="method">
  追加一条 `Message` 到对话中。同步返回（不是 `suspend`）。用户消息会触发防抖后的预加载；助手消息让 SDK 把匹配到的广告绑定到广告位上。

  ```kotlin theme={null}
  session.addMessage(Message(id = "m1", role = Role.USER, content = "Hi"))
  session.addMessage(
      Message(id = "m2", role = Role.USER, content = "Hi again"),
      AddMessageOptions(trackOnly = true),
  )
  ```

  当 `trackOnly = true` 时，预加载会照常发送（用于上报分析数据），但不会生成广告。
</ParamField>

<ParamField path="createAd(messageId, options)" type="method">
  返回指定 `messageId` 对应的 `Ad`。幂等——同一个 `messageId` + `code` + `theme` 的多次调用会返回同一个 `Ad`。请缓存返回值。

  ```kotlin theme={null}
  val ad = session.createAd("m2")
  val sidebar = session.createAd("m2", AdOptions(code = "sidebar", theme = "dark"))
  ```
</ParamField>

<ParamField path="updateOptions(partial)" type="method">
  动态更新会话级别的可变字段。见 [实践指南 → 动态更新会话选项](/sdk/kotlin/guides#动态更新会话选项)。
</ParamField>

<ParamField path="destroy()" type="method">
  释放会话：取消预加载、销毁广告、释放 WebView 资源。幂等。`close()` 是它的别名（实现 `AutoCloseable`）。
</ParamField>

<ParamField path="events" type="SharedFlow<AdEvent>" property>
  与 `onEvent` 同源的事件 Flow。适合在 ViewModel 与协程管道中订阅。
</ParamField>

<ParamField path="messages" type="List<Message>" property>
  当前会话追踪到的消息只读快照。
</ParamField>

<ParamField path="sessionId" type="UUID?" property>
  服务端分配的 session ID。在首次预加载成功之前为 `null`。
</ParamField>

<ParamField path="disabled" type="Boolean" property>
  当服务端通过 `/init` 永久禁用会话（例如地域限制）时为 `true`。后续预加载会被跳过。
</ParamField>

<ParamField path="destroyed" type="Boolean" property>
  `destroy()` 被调用后为 `true`。
</ParamField>

## `MutablePublisherOptions`

`session.updateOptions(...)` 接受的 `SessionOptions` 子集。所有字段均为可选——非 null 会覆盖原值，null 表示保持不变。

<ParamField path="variantId" type="String?" optional />

<ParamField path="regulatory" type="Regulatory?" optional />

<ParamField path="userEmail" type="String?" optional />

<ParamField path="advertisingId" type="String?" optional />

## `Message`

<ParamField path="id" type="String" required>消息的唯一 ID。</ParamField>
<ParamField path="role" type="Role" required>`Role.USER` 或 `Role.ASSISTANT`。</ParamField>
<ParamField path="content" type="String" required>消息文本。</ParamField>
<ParamField path="createdAt" type="Date" optional>默认 `Date()`。</ParamField>

## `AdOptions`

<ParamField path="code" type="String" optional>广告位 code。默认 `"inlineAd"`。</ParamField>
<ParamField path="theme" type="String?" optional>透传到 iframe 的主题提示（例如 `"dark"`）。</ParamField>

## `AddMessageOptions`

<ParamField path="trackOnly" type="Boolean" optional>
  为 `true` 时，预加载仍会发送（用于上报分析数据），但不会为这条消息生成广告。默认 `false`。
</ParamField>

## UI

### `InlineAd`（Compose，推荐）

```kotlin theme={null}
@Composable
public fun InlineAd(
    messageId: String,
    session: Session,
    code: String? = null,
    theme: String? = null,
    modifier: Modifier = Modifier,
)
```

为指定 `messageId` 挂载广告。内部会调用 `session.createAd(...)`，挂载一个池化的 `WebView`，并把容器几何信息上报给 iframe。可以安全地放在 `LazyColumn` 中——底层 `Ad` 和 `WebView` 会在重组与滚动复用中保持存活。

另一个重载直接接收已经解析好的 `Ad`：

```kotlin theme={null}
@Composable
public fun InlineAd(ad: Ad, modifier: Modifier = Modifier)
```

### `InlineAdView`（View 互操作）

```kotlin theme={null}
public class InlineAdView(context: Context) : FrameLayout {
    public var onHeightChange: ((Float) -> Unit)?
    public fun bind(messageId: String, session: Session, code: String? = null, theme: String? = null)
}
```

适用于没有使用 Compose 的项目。inflate / 实例化后调用一次 `bind(messageId, session)`；订阅 `onHeightChange` 来撑开外层容器（例如 `RecyclerView` 行）。

## `AdEvent`

`AdEvent` 是 sealed class，每个 case 携带一个强类型的 payload。可以通过 `event.name` 拿到稳定的字符串标识。

### `AdEvent.Filled` — wire name `ad.filled`

返回了一个广告并绑定到了广告位。

<Expandable title="Filled">
  <ParamField path="bidId" type="UUID" />

  <ParamField path="code" type="String">该广告被匹配到的 placement code。当发布方配置了多个 `enabledPlacementCodes` 时用于区分。</ParamField>

  <ParamField path="revenue" type="Double?" />
</Expandable>

### `AdEvent.NoFill` — wire name `ad.no-fill`

广告位没有返回广告（服务端 skip）。

<Expandable title="NoFill">
  <ParamField path="skipCode" type="String">跳过的原因码。</ParamField>
</Expandable>

### `AdEvent.AdHeight` — wire name `ad.height`

iframe 上报了新的高度。用于撑开 `RecyclerView` 行的高度。`InlineAd` composable 会自动处理这件事。

<Expandable title="AdHeight">
  <ParamField path="bidId" type="UUID" />

  <ParamField path="messageId" type="String" />

  <ParamField path="height" type="Float" />
</Expandable>

### `AdEvent.Viewed` — wire name `ad.viewed`

广告被用户看到（符合 IAB MRC 可视性标准）。

<Expandable title="Viewed">
  <ParamField path="bidId" type="UUID" />

  <ParamField path="content" type="String" />

  <ParamField path="messageId" type="String" />

  <ParamField path="format" type="String" />

  <ParamField path="revenue" type="Double?" />
</Expandable>

### `AdEvent.Clicked` — wire name `ad.clicked`

用户点击了广告。

<Expandable title="Clicked">
  <ParamField path="bidId" type="UUID" />

  <ParamField path="content" type="String" />

  <ParamField path="messageId" type="String" />

  <ParamField path="url" type="String" />

  <ParamField path="format" type="String" />

  <ParamField path="area" type="String">被点击的广告区域。</ParamField>
</Expandable>

### `AdEvent.RenderStarted` — wire name `ad.render-started`

收到广告内容的第一个 token。

<Expandable title="RenderStarted">
  <ParamField path="bidId" type="UUID" />
</Expandable>

### `AdEvent.RenderCompleted` — wire name `ad.render-completed`

广告内容流式输出完毕。

<Expandable title="RenderCompleted">
  <ParamField path="bidId" type="UUID" />
</Expandable>

### `AdEvent.Error` — wire name `ad.error`

SDK 在服务广告过程中遇到错误。

<Expandable title="Error">
  <ParamField path="message" type="String" />

  <ParamField path="errCode" type="String" />
</Expandable>

### `AdEvent.VideoStarted` — wire name `video.started`

<Expandable title="VideoStarted">
  <ParamField path="bidId" type="UUID" />
</Expandable>

### `AdEvent.VideoCompleted` — wire name `video.completed`

<Expandable title="VideoCompleted">
  <ParamField path="bidId" type="UUID" />
</Expandable>

### `AdEvent.RewardGranted` — wire name `reward.granted`

激励视频流程中，用户达到发奖条件时触发。

<Expandable title="RewardGranted">
  <ParamField path="bidId" type="UUID" />
</Expandable>
