Repository navigation
feat: Kaapi Agentic Onboarding Chatbot Flow #1300
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Ayush8923
wants to merge
29
commits into
main
Choose a base branch
from
feat/kaapi-chatbot-flow-v2
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
29 commits
Select commit
Hold shift + click to select a range
dbba788
feat(*): init chatbot flow
Ayush8923 e0130e8
feat: Chatbot State Management (#1301)
Ayush8923 0103f45
Merge branch 'main' into feat/kaapi-chatbot-flow-v2
Ayush8923 8d9919c
fix: test cases updates
Ayush8923 2584679
Merge branch 'main' of https://github.com/ProjectTech4DevAI/kaapi-bac…
Ayush8923 54c00ad
fix: remove the unwanted migration
Ayush8923 00bbe9a
fix: few clenaups
Ayush8923 e9927df
fix: cleanups and save collected fields in db
Ayush8923 90a2cbd
fix: refinement system prompt
Ayush8923 e884d24
fix: implement the state management api flow creation
Ayush8923 3e09675
feat: added the feature flag
Ayush8923 c18a3a8
chore: remove the unused code
Ayush8923 440e5c8
fix: few updates on the get request
Ayush8923 f44ba82
fix: cleanups
Ayush8923 daf4b92
fix: refactoring
Ayush8923 7d0b166
Merge branch 'main' of https://github.com/ProjectTech4DevAI/kaapi-bac…
Ayush8923 ab34262
fix: update test cases
Ayush8923 26f70a2
fix: cleanups
Ayush8923 548e869
fix: coderabbit suggestion
Ayush8923 eaacc3d
Merge branch 'main' into feat/kaapi-chatbot-flow-v2
Ayush8923 b193156
fix: restructure the flows
Ayush8923 0a2af91
fix: update the create.md
Ayush8923 3b8d55f
fix: few more test cases updates
Ayush8923 3f0a743
fix: get the antropic api key via credentials
Ayush8923 46d6533
fix: update the updated at
Ayush8923 4cf240d
fix: remove the duplicate code
Ayush8923 b60fa1b
fix: few more cleanups
Ayush8923 251c34f
fix: remove the logger
Ayush8923 86afc38
fix: remove the unwanted code comment
Ayush8923 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
307 changes: 307 additions & 0 deletions
307
backend/app/alembic/versions/088_add_chatbot_session.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,307 @@ | ||
| """add chatbot, flow version, session and message tables | ||
|
|
||
| Revision ID: 088 | ||
| Revises: 087 | ||
| Create Date: 2026-10-20 00:00:00.000000 | ||
| """ | ||
|
|
||
| import sqlalchemy as sa | ||
| import sqlmodel.sql.sqltypes | ||
| from alembic import op | ||
| from sqlalchemy.dialects import postgresql | ||
|
|
||
| revision = "088" | ||
| down_revision = "087" | ||
| branch_labels = None | ||
| depends_on = None | ||
|
|
||
|
|
||
| def upgrade(): | ||
| op.create_table( | ||
| "chatbot", | ||
| sa.Column( | ||
| "id", | ||
| sa.Uuid(), | ||
| nullable=False, | ||
| comment="Chatbot identifier used in API paths", | ||
| ), | ||
| sa.Column( | ||
| "name", | ||
| sqlmodel.sql.sqltypes.AutoString(length=255), | ||
| nullable=False, | ||
| comment="Display name of the chatbot shown in the UI", | ||
| ), | ||
| sa.Column( | ||
| "organization_id", | ||
| sa.Integer(), | ||
| nullable=False, | ||
| comment="Organization that owns the chatbot", | ||
| ), | ||
| sa.Column( | ||
| "project_id", | ||
| sa.Integer(), | ||
| nullable=False, | ||
| comment="Project that owns the chatbot", | ||
| ), | ||
| sa.Column( | ||
| "inserted_at", | ||
| sa.DateTime(), | ||
| nullable=False, | ||
| comment="Timestamp when the chatbot was created", | ||
| ), | ||
| sa.Column( | ||
| "updated_at", | ||
| sa.DateTime(), | ||
| nullable=False, | ||
| comment="Timestamp when the chatbot was last updated", | ||
| ), | ||
| sa.Column( | ||
| "deleted_at", | ||
| sa.DateTime(), | ||
| nullable=True, | ||
| comment="Soft-delete timestamp; the row is kept because sessions reference it", | ||
| ), | ||
| sa.ForeignKeyConstraint( | ||
| ["organization_id"], ["organization.id"], ondelete="CASCADE" | ||
| ), | ||
| sa.ForeignKeyConstraint(["project_id"], ["project.id"], ondelete="CASCADE"), | ||
| sa.PrimaryKeyConstraint("id"), | ||
| ) | ||
| op.create_index( | ||
| op.f("ix_chatbot_organization_id"), | ||
| "chatbot", | ||
| ["organization_id"], | ||
| unique=False, | ||
| ) | ||
| op.create_index( | ||
| op.f("ix_chatbot_project_id"), "chatbot", ["project_id"], unique=False | ||
| ) | ||
|
|
||
| op.create_table( | ||
| "chatbot_flow_version", | ||
| sa.Column( | ||
| "id", | ||
| sa.Uuid(), | ||
| nullable=False, | ||
| comment="Flow version identifier pinned by sessions", | ||
| ), | ||
| sa.Column( | ||
| "chatbot_id", | ||
| sa.Uuid(), | ||
| nullable=False, | ||
| comment="Chatbot this flow version belongs to", | ||
| ), | ||
| sa.Column( | ||
| "version", | ||
| sa.Integer(), | ||
| nullable=False, | ||
| comment="Sequential version number per chatbot, starting at 1", | ||
| ), | ||
| sa.Column( | ||
| "nodes", | ||
| postgresql.JSONB(astext_type=sa.Text()), | ||
| nullable=False, | ||
| comment="React Flow nodes as saved by the UI: [{id, type (input/output/coordinator/onboarding/rag), position {x, y}, data}]; agent node data carries config_id, config_version, prompt", | ||
| ), | ||
| sa.Column( | ||
| "edges", | ||
| postgresql.JSONB(astext_type=sa.Text()), | ||
| nullable=False, | ||
| server_default=sa.text("'[]'::jsonb"), | ||
| comment="React Flow edges as saved by the UI: [{id, source, target, sourceHandle, targetHandle, data}]", | ||
| ), | ||
| sa.Column( | ||
| "is_live", | ||
| sa.Boolean(), | ||
| nullable=False, | ||
| server_default=sa.text("false"), | ||
| comment="True for the single published version new sessions run on; live versions are immutable, the highest non-live version is the draft", | ||
| ), | ||
| sa.Column( | ||
| "inserted_at", | ||
| sa.DateTime(), | ||
| nullable=False, | ||
| comment="Timestamp when the version was created", | ||
| ), | ||
| sa.Column( | ||
| "updated_at", | ||
| sa.DateTime(), | ||
| nullable=False, | ||
| comment="Timestamp when the draft was last saved or the version was published/unpublished", | ||
| ), | ||
| sa.ForeignKeyConstraint(["chatbot_id"], ["chatbot.id"], ondelete="CASCADE"), | ||
| sa.PrimaryKeyConstraint("id"), | ||
| sa.UniqueConstraint( | ||
| "chatbot_id", | ||
| "version", | ||
| name="uq_chatbot_flow_version_chatbot_version", | ||
| ), | ||
| ) | ||
| op.create_index( | ||
| op.f("ix_chatbot_flow_version_chatbot_id"), | ||
| "chatbot_flow_version", | ||
| ["chatbot_id"], | ||
| unique=False, | ||
| ) | ||
| op.create_index( | ||
| "uq_chatbot_flow_version_live_chatbot", | ||
| "chatbot_flow_version", | ||
| ["chatbot_id"], | ||
| unique=True, | ||
| postgresql_where=sa.text("is_live"), | ||
| ) | ||
|
|
||
| op.create_table( | ||
| "chatbot_session", | ||
| sa.Column( | ||
| "id", | ||
| sa.Uuid(), | ||
| nullable=False, | ||
| comment="Session identifier returned to the caller", | ||
| ), | ||
| sa.Column( | ||
| "chatbot_id", | ||
| sa.Uuid(), | ||
| nullable=False, | ||
| comment="Chatbot this session runs; tenant scope comes from the chatbot", | ||
| ), | ||
| sa.Column( | ||
| "flow_version_id", | ||
| sa.Uuid(), | ||
| nullable=False, | ||
| comment="Live flow version pinned at creation, so publishing never changes a running conversation", | ||
| ), | ||
| sa.Column( | ||
| "contact_ref", | ||
| sqlmodel.sql.sqltypes.AutoString(length=500), | ||
| nullable=False, | ||
| comment="Caller-side identifier of the end user (e.g. a Glific contact id); opaque to Kaapi", | ||
| ), | ||
| sa.Column( | ||
| "active_node_id", | ||
| sqlmodel.sql.sqltypes.AutoString(length=255), | ||
| nullable=False, | ||
| comment="React Flow node id inside the pinned flow version that handles the next turn", | ||
| ), | ||
| sa.Column( | ||
| "status", | ||
| sa.Enum( | ||
| "active", | ||
| "inactive", | ||
| name="chatbotsessionstatusenum", | ||
| ), | ||
| nullable=False, | ||
| comment="Session in use: active, or inactive once superseded by a newer session for the same chatbot + contact_ref or the chatbot was deleted", | ||
| ), | ||
| sa.Column( | ||
| "completion_status", | ||
| sa.Enum( | ||
| "in_progress", | ||
| "complete", | ||
| "abandoned", | ||
| name="chatbotcompletionstatusenum", | ||
| ), | ||
| nullable=False, | ||
| server_default="in_progress", | ||
| comment="Field collection progress: in_progress, complete once every required field is gathered, or abandoned when deactivated while in_progress", | ||
| ), | ||
| sa.Column( | ||
| "collected_fields", | ||
| postgresql.JSON(astext_type=sa.Text()), | ||
| nullable=False, | ||
| comment="Flat map of field name -> value gathered from the user so far", | ||
| ), | ||
| sa.Column( | ||
| "inserted_at", | ||
| sa.DateTime(), | ||
| nullable=False, | ||
| comment="Timestamp when the session was created", | ||
| ), | ||
| sa.Column( | ||
| "updated_at", | ||
| sa.DateTime(), | ||
| nullable=False, | ||
| comment="Timestamp when the session was last updated", | ||
| ), | ||
| sa.ForeignKeyConstraint(["chatbot_id"], ["chatbot.id"], ondelete="RESTRICT"), | ||
| sa.ForeignKeyConstraint( | ||
| ["flow_version_id"], ["chatbot_flow_version.id"], ondelete="RESTRICT" | ||
| ), | ||
| sa.PrimaryKeyConstraint("id"), | ||
| ) | ||
| op.create_index( | ||
| op.f("ix_chatbot_session_flow_version_id"), | ||
| "chatbot_session", | ||
| ["flow_version_id"], | ||
| unique=False, | ||
| ) | ||
| op.create_index( | ||
| op.f("ix_chatbot_session_contact_ref"), | ||
| "chatbot_session", | ||
| ["contact_ref"], | ||
| unique=False, | ||
| ) | ||
| op.create_index( | ||
| "ix_chatbot_session_chatbot_contact", | ||
| "chatbot_session", | ||
| ["chatbot_id", "contact_ref"], | ||
| unique=False, | ||
| ) | ||
| op.create_index( | ||
| "uq_chatbot_session_active_chatbot_contact", | ||
| "chatbot_session", | ||
| ["chatbot_id", "contact_ref"], | ||
| unique=True, | ||
| postgresql_where=sa.text("status = 'active'"), | ||
| ) | ||
|
|
||
| op.create_table( | ||
| "chatbot_session_message", | ||
| sa.Column("id", sa.Uuid(), nullable=False, comment="Unique identifier"), | ||
| sa.Column( | ||
| "session_id", | ||
| sa.Uuid(), | ||
| nullable=False, | ||
| comment="Reference to the owning chatbot session", | ||
| ), | ||
| sa.Column( | ||
| "role", | ||
| sa.Enum("system", "user", "assistant", name="chatbotmessageroleenum"), | ||
| nullable=False, | ||
| comment="Speaker: user or assistant (system is reserved; the prompt lives on the flow node)", | ||
| ), | ||
| sa.Column( | ||
| "content", | ||
| sqlmodel.sql.sqltypes.AutoString(), | ||
| nullable=False, | ||
| comment="Message text", | ||
| ), | ||
| sa.Column( | ||
| "node_id", | ||
| sqlmodel.sql.sqltypes.AutoString(length=255), | ||
| nullable=True, | ||
| comment="React Flow node id of the pinned flow that was active for this turn", | ||
| ), | ||
| sa.Column( | ||
| "inserted_at", | ||
| sa.DateTime(), | ||
| nullable=False, | ||
| comment="Timestamp when the message was stored; defines transcript order", | ||
| ), | ||
| sa.ForeignKeyConstraint( | ||
| ["session_id"], ["chatbot_session.id"], ondelete="CASCADE" | ||
| ), | ||
| sa.PrimaryKeyConstraint("id"), | ||
| ) | ||
| op.create_index( | ||
| op.f("ix_chatbot_session_message_session_id"), | ||
| "chatbot_session_message", | ||
| ["session_id"], | ||
| unique=False, | ||
| ) | ||
|
|
||
|
|
||
| def downgrade(): | ||
| raise NotImplementedError( | ||
| "not reversible: dropping chatbot tables discards chatbot flows and stored conversations" | ||
| ) | ||
22 changes: 22 additions & 0 deletions
22
backend/app/alembic/versions/089_add_chatbot_feature_flag.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| """add CHATBOT feature flag key | ||
|
|
||
| Revision ID: 089 | ||
| Revises: 088 | ||
| Create Date: 2026-10-23 00:00:00.000000 | ||
| """ | ||
|
|
||
| from alembic import op | ||
|
|
||
| revision = "089" | ||
| down_revision = "088" | ||
| branch_labels = None | ||
| depends_on = None | ||
|
|
||
|
|
||
| def upgrade(): | ||
| with op.get_context().autocommit_block(): | ||
| op.execute("ALTER TYPE featureflagkey ADD VALUE IF NOT EXISTS 'CHATBOT'") | ||
|
|
||
|
|
||
| def downgrade(): | ||
| pass |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| Create a chatbot in the caller's project and return it (`201`). | ||
|
|
||
| Only `name` is required (1–255 characters; display only). A new chatbot has no flow: its first `PUT /chatbots/{chatbot_id}/flow` goes live at once, after which sessions can start. Later saves are drafts that go live with `POST /chatbots/{chatbot_id}/flow/publish`. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| Start a conversation between a chatbot and an end user and return `{session_id, chatbot_id, flow_version, active_node_id}` (`201`). | ||
|
|
||
| The session is pinned to the chatbot's live flow version and starts on its entry node (the agent node the `input` node leads to, or the flow's only agent node). Every turn runs that pinned version, so publishing a newer flow applies to new sessions only. `contact_ref` is the caller's own identifier for the end user and is stored as-is. | ||
|
|
||
| A contact has at most one active session per chatbot. Creating a session marks the contact's previous `active` sessions of this chatbot as `inactive`, in the same transaction; those still `in_progress` become `abandoned`, while `complete` ones stay `complete`. Sessions of other chatbots or other contacts are untouched. Returns 404 if the chatbot doesn't exist in this project or was deleted, 409 if the chatbot has no published flow (publish the flow first) or another session for the same contact was created concurrently (retry). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| Soft-delete a chatbot; returns `{"message": "Chatbot deleted successfully"}`. It disappears from list/get and its flow can no longer be edited, published, or used for new sessions. | ||
|
|
||
| In the same transaction every `active` session of the chatbot becomes `inactive` (those still `in_progress` become `abandoned`; `complete` ones stay `complete`), so further messages to them return 409. Stored sessions and transcripts are kept. Returns 404 if the chatbot doesn't exist in this project or was already deleted. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| Get one chatbot of the caller's project by `chatbot_id`. | ||
|
|
||
| Returns 404 if the chatbot doesn't exist in this project or was deleted. The chatbot's flow is fetched separately with `GET /chatbots/{chatbot_id}/flow`. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| Get a version of the chatbot's React Flow graph: `{id, chatbot_id, version, is_live, nodes, edges, inserted_at, updated_at}`. | ||
|
|
||
| With `?version=N` that version is returned. Without it, the draft is returned if one exists (the highest version when it is not live), otherwise the live version. `nodes` and `edges` come back exactly as saved, with React Flow keys (`sourceHandle`, `targetHandle`, and UI-only keys such as `measured`). Agent nodes of a published version carry the pinned `data.config_version`. | ||
|
|
||
| Returns 404 if the chatbot doesn't exist in this project, has no flow yet, or has no such version. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| Get the most recently created chatbot session for `contact_ref` in the caller's project, optionally narrowed to one chatbot with `chatbot_id`. | ||
|
|
||
| `contact_ref` is required and matched exactly. Omit `chatbot_id` to get the contact's newest session across the project's chatbots — the response's `chatbot_id` and `chatbot_name` say which one. Sessions of deleted chatbots are not returned. | ||
|
|
||
| The response carries the pinned `flow_version`, the `active_node_id` and that node's `prompt`, the session `status` (`active`, or `inactive` once a newer session for the same contact and chatbot was created or the chatbot was deleted), its `completion_status` (`in_progress` until every field the prompt asks for is collected, then `complete`; `abandoned` if it was deactivated while still `in_progress`), and the flat `collected_fields` map (`{field_name: value}`) gathered so far. Returns 404 when no matching session exists in this project. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| List the caller's project's chatbots, most recently updated first. Deleted chatbots are excluded. | ||
|
|
||
| Paginate with `skip` (default 0) and `limit` (1–100, default 100). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| Publish the chatbot's draft so new sessions run on it. Returns the now-live version. | ||
|
|
||
| The draft is validated strictly: node ids are unique; at most one `input` and one `output` node; every edge's `source` and `target` is a node in the flow; every agent node has `data.config_id` and a non-empty `data.prompt`, and its config resolves to an Anthropic text config in this project with a model set (and a valid thinking budget). The project must have Anthropic credentials configured, since agent nodes call Anthropic with the project's own key. Only `onboarding` agent nodes can run for now — `coordinator` and `rag` nodes are rejected as not supported yet. The flow needs an entry node: with no edges it must contain exactly one agent node; otherwise the `input` node must have exactly one outgoing edge, leading to an agent node. A node without `data.config_version` gets the config's latest version written into the stored node, so later config edits don't change the published flow. | ||
|
|
||
| The previous live version (if any) stops being live in the same transaction. Sessions already running stay pinned to the version they started on. Returns 404 for an unknown chatbot, 409 if there is no draft to publish (save the flow first) or on a concurrent change, and 422 listing every validation problem. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| Save the chatbot's flow: `{nodes, edges}` in React Flow shape. Returns the saved version. | ||
|
|
||
| The **first** save of a chatbot creates version 1 and makes it live immediately, so the chatbot can run without a separate publish. Because it goes live, it gets the same strict validation as publish (see the publish endpoint) and its missing `config_version`s are pinned to the latest; an invalid first flow returns 422 and nothing is saved. | ||
|
|
||
| Every later save is a draft that needs a publish to go live: if the highest version is not live it is overwritten, otherwise a new version `max + 1` is created with `is_live: false`. Live versions are never modified, so editing never affects running conversations. | ||
|
|
||
| Draft saves check only the shape, so half-built flows save: each node needs `id` (1–255 chars), `type` (`input`, `output`, `coordinator`, `onboarding`, `rag`), `position {x, y}` and an object `data`; agent nodes (`coordinator`, `onboarding`, `rag`) may carry `data.config_id` (UUID), `data.config_version` (≥ 1) and `data.prompt`. Each edge needs `id`, `source`, `target`; `sourceHandle`, `targetHandle` and `data` (e.g. `intent`, `description`) are optional. Extra keys are stored and returned as sent. Returns 404 for an unknown chatbot, 409 if the flow was changed concurrently (reload and retry), and 422 for an invalid first save. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| Queue one turn of a chatbot session; the bot reply is delivered asynchronously to `webhook_url`. | ||
|
|
||
| The user `message` is stored immediately (tagged with the session's active node) and the response is `202` with `status: "queued"`. Once the turn completes, Kaapi POSTs `{"success": true, "data": {"session_id", "chatbot_id", "node_id", "reply", "status", "completion_status", "collected_fields"}}` to `webhook_url` (HMAC-signed when the project has a webhook secret). On a model, config or flow failure it POSTs `{"success": false, "error": "...", "data": {"session_id"}}` instead. | ||
|
|
||
| The turn runs the session's active node of its pinned flow version: the node's `data.prompt` is the system prompt and its `data.config_id` / `data.config_version` supply the model. Each turn re-reads the conversation against that prompt and saves every field the user has given into `collected_fields`, a flat `{field_name: value}` map with snake_case keys (values are only ever taken from what the user said; a correction overwrites the old value). `completion_status` is `complete` once every required field is collected and `in_progress` otherwise; it is computed from a structured extraction, not from the reply text. A `complete` session still accepts messages. `status` (`active`/`inactive`) is separate and says whether the session is in use: once a newer session is created for the same contact and chatbot, or the chatbot is deleted, this one is `inactive` and rejects new messages with 409. A turn that was already queued when that happened is not run; Kaapi POSTs the failure payload with error `[KAAPI] Chatbot session was superseded by a newer session; start a new session.` instead. | ||
|
|
||
| On the first call of a session, omit `message` to get the bot's opening greeting; after that `message` is required. `webhook_url` must be a public HTTPS URL. Returns 404 if the session isn't in the caller's project, 409 if the session is inactive, and 422 for an invalid `webhook_url` or a missing `message` on a started session. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| Rename a chatbot. Only `name` can change; omitting it leaves the chatbot unchanged. | ||
|
|
||
| Returns 404 if the chatbot doesn't exist in this project or was deleted. |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.