Features
GenAI

GenAI

GenAI is lk-wiz's Bedrock-backed writing assistant. It drafts a post from an idea, rewrites existing content on instruction, and proofreads a draft for grammar and LinkedIn fit. It has no lifecycle of its own — every call is stateless request/response; nothing is queued, scheduled, or tracked by this domain.

This page describes the product-facing behavior. For exact request/response shapes and error codes, see the GenAI API reference. For programmatic access from an AI client, see GenAI MCP tools — and note that the MCP tools behave differently from the HTTP API in important ways (see MCP vs. HTTP API). The underlying spec this page is based on is specs/features/genai.md in the repo.

At a glance

CapabilityEndpointPersists?
GeneratePOST /api/genai/generateNo — returns text only
IteratePOST /api/genai/iterateNo — returns a suggestion only
ProofreadPOST /api/genai/proofreadNo — returns annotations only

Every call requires the caller to be a member of the target workspace (any role — there's no extra gate for viewers here), and every call is timed and counted via CloudWatch metrics (GenAIGeneration, GenAILatencyMs, tagged by gen_type: generate / iterate / proofread).

⚠️

Streaming is not wired up. Even though Bedrock and the shared client library (common.bedrock.generate_streaming) support token-by-token streaming, none of the three endpoints below use it — API Gateway's HTTP API doesn't support Lambda response streaming, so every call blocks until Bedrock finishes and returns the full text in one JSON response. If you're building a UI against these endpoints, don't expect incremental chunks.

Generate

Click "Generate Post" on a triaged idea, and lk-wiz builds a prompt from up to four layers — in increasing priority: a built-in default persona, an optional saved prompt template, an optional one-off system-instruction override, and per-call knobs (audience, tone, language, length) — then sends it to Bedrock and returns the draft text.

POST /api/genai/generate
{
  "workspace_id": "ws_123",
  "idea_id": "idea_456",
  "prompt_id": "prompt_789",
  "audience": "Engineering leaders",
  "tone": "confident",
  "length": "medium"
}

Up to 5 of the workspace's example posts are pulled in too, ranked by tag overlap with the idea — so if you've tagged your best-performing posts as "examples," GenAI leans on the ones most relevant to what you're writing about.

⚠️

If you pass a prompt_id that doesn't resolve to a real saved prompt, generation fails with a 404 rather than silently falling back to a default. Compare this with Iterate below, which is more forgiving.

The response is just { "content": "...", "idea_id": "..." } — nothing is saved. Saving the draft as a real post is a separate step (POST /api/posts, see Posts § Create).

Iterate

Once you're editing a post in the canvas, the GenAI assistant panel lets you type a natural-language instruction ("make the hook stronger", "add a call to action", "shorten this to 3 paragraphs") and get back a rewritten version.

POST /api/genai/iterate
{
  "workspace_id": "ws_123",
  "post_id": "post_abc",
  "instruction": "Make the hook stronger and add a call to action",
  "current_content": "Original draft text..."
}

This call never touches the post — it returns a suggestion string for the panel to display. Accepting it is a separate client-side action that replaces the editor content and records a genai_accept version snapshot (see Posts § Versions); rejecting it just discards the response.

Unlike Generate, an unresolved prompt_id here does not error — it silently falls back to a generic "edit this post" persona. Iteration always has something reasonable to fall back to; generation from scratch does not.

Proofread

While you type, lk-wiz automatically re-checks your draft for grammar, tone, LinkedIn-specific issues (character count vs. the 3000-char cap, too many emoji, hashtag count), roughly 3 seconds after you stop typing.

POST /api/genai/proofread
{ "workspace_id": "ws_123", "post_id": "post_abc", "content": "..." }

The response is a list of annotations, each anchored to a [start, end] character range in the text, with a type (grammar / tone / suggestion), a human-readable message, and a proposed suggestion replacement. Click an annotation in the editor to apply or dismiss it.

Proofreading never fails outright — if the model's response can't be parsed as a JSON array (malformed output, wrapped in prose, etc.), you just get an empty annotation list back, not an error toast.

MCP vs. HTTP API

If you're driving lk-wiz from an AI client (Claude Desktop, Claude Code) rather than the web UI, the GenAI MCP tools look similar — generate_post and iterate_post — but behave differently under the hood:

  • They persist. generate_post immediately creates a new draft post in the pipeline; iterate_post immediately overwrites the target post's content. There's no "preview, then accept" step like the web UI's canvas — an MCP call changes real data right away.
  • Less prompt customization. No overrides, audience/tone/ language/length knobs, or tag-ranked examples — just an optional prompt_id for generation, and no persona customization at all for iteration.
  • No proofreading tool. Proofreading is HTTP-API/web-UI only.

See GenAI MCP tools for the full contract.

See also