Langkau ke kandungan

Jambatan sembang

Penyedia Nilai wayar Pengangkutan Jenis ruang
Slack slack Socket Mode (WSS keluar) slack

Slack ialah satu-satunya penyedia. ChatProvider ialah enum bernilai tunggal dan cc_server mendaftarkan satu plugin. Skema, setiap carian dan setiap indeks unik berkunci pada provider, jadi id tidak pernah merentas penyedia dan menambah satu penyedia hanyalah perubahan di sisi pelayan.

Satu apl di sisi penyedia bagi setiap ruang kerja × penyedia.

Nama perintah adalah bagi setiap apl (cc secara lalai, jadi /cc). Pentadbir boleh menamakannya semula; jambatan kemudian menggunakan apa sahaja yang terakhir digunakan untuk memanggilnya.

Perintah Kesan
/cc help (atau /cc tanpa kata kerja) Menyenaraikan apa yang bot boleh lakukan
/cc link <code> Menebus kod sekali guna dan memautkan identiti sembang penghantar
/cc ticket <title> Memfailkan tiket setempat yang dilaporkan oleh ahli yang dipautkan
/cc ticket <title> | <description> Sama, dengan segala-galanya selepas | pertama sebagai perihalan
Kata kerja tidak dikenali Melaporkan kata kerja yang tidak dikenali serta teks bantuan

Cara untuk menghubungi ejen:

Gerak isyarat Tingkah laku
@bot … dalam saluran Membuka utas Slack dan ruang Control Center yang sepadan; ejen membalas dalam utas Slack itu
Balasan dalam utas Slack yang dijambatkan Meneruskan ruang Control Center yang sama — tiada sebutan diperlukan
Mesej biasa dalam saluran Diabaikan (tidak ditujukan kepada bot dan bukan dalam utas Slack yang dijambatkan)
DM kepada bot Satu ruang Control Center bagi setiap perbualan DM; menetapkan tajuk utas Slack dan status “is thinking…” semasa ejen bekerja

Diisytiharkan oleh penerang penyedia, dan itulah yang menjana dialog sambungan serta mengesahkan penyerahan.

Id medan Label Wajib Awalan Tempat ia berada
botToken Token OAuth pengguna bot Ya xoxb- OAuth & Permissions
appToken Token peringkat apl Ya xapp- Basic Information → App-Level Tokens, skop connections:write
configRefreshToken Token segar semula konfigurasi apl Tidak xoxe Token konfigurasi apl pada api.slack.com/apps

configRefreshToken ialah kelayakan pengurusan apl: tanpanya sambungan tetap berfungsi, tetapi bot tidak boleh dicipta atau disunting dari Control Center. Ia berputar pada setiap penggunaan dan nilai yang berputar itu disimpan serta-merta.

Nilai dipangkas, kunci yang tidak diisytiharkan digugurkan dan ketidakpadanan awalan ditolak dengan ayat yang sama pada klien dan pelayan. Medan wajib mesti hadir pada setiap sambungan; medan pilihan yang dibiarkan kosong mengekalkan apa sahaja yang telah tersimpan.

Skop token bot:

app_mentions:read
assistant:write
channels:history
chat:write
commands
groups:history
im:history
users:read
users:read.email

Langganan peristiwa bot:

app_home_opened
app_mention
message.channels
message.groups
message.im

Tetapan struktur yang ditegaskan oleh Control Center apabila ia mencipta atau menyunting apl: Socket Mode didayakan, tiada URL permintaan, tab Messages didayakan dan boleh ditulis, bot always_online, skop dan peristiwa yang diperlukan digabungkan ke dalam apa sahaja yang sudah ada pada apl itu (tidak pernah dikurangkan) dan satu perintah slash yang membawa perihalan File a ticket or link your Control Center account — penanda yang mengenal pasti perintah milik Control Center sendiri dalam manifes yang dieksport.

Keadaan Wayar Maksud
Tidak disambungkan disconnected Tiada kelayakan disimpan untuk ruang kerja × penyedia ini
Menyambung… connecting Kelayakan disimpan, pengangkutan sedang mendail atau mendail semula
Langsung connected Pengangkutan hidup dan menerima peristiwa
Ralat sambungan error Disimpan tetapi gagal; ralat penyedia itu sendiri ditunjukkan bersama

Penyambungan semula menggunakan backoff eksponen dengan jitter, dihadkan pada 30 saat. Putaran soket yang dimulakan oleh penyedia akan menyambung semula dengan segera tanpa meningkatkan backoff. Kelayakan yang ditolak (invalid_auth, not_authed, token_revoked, account_inactive, token_expired, invalid_app_id) atau skop yang hilang bersifat muktamad: jambatan berhenti mencuba semula sehingga kelayakan baharu tiba.

Jambatan ini ditulis untuk permukaan terkaya dan menurunkan keupayaan satu demi satu.

Keupayaan Slack Kesan apabila tiada
streaming ya Balasan penuh disiarkan sekali, pada penghujungnya
streamingRequiresThread ya Sasaran balasan tanpa sauh utas menyiarkan balasan penuh
ephemeralMessages ya Jawapan perintah slash tanpa pemegang balasan yang boleh digunakan akan digugurkan (penolakan sentiasa disiarkan dalam utas)
threadStatus ya Tiada baris sementara “is thinking…”
threadTitle ya Utas sembang mengekalkan tajuk lalainya
slashCommands ya Tiada permukaan /cc
taskCards ya Teks sahaja — tiada kad di atas balasan dan tiada pautan “View in Control Center”
maxMessageLength 39,000 Balasan yang lebih panjang dipotong dengan penunjuk ke Control Center
maxStreamChunkLength 3,800 Tambahan dipecah pada sempadan perenggan, baris atau ruang kosong

Mengiklankan penstriman bukan bermakna menjanjikannya: milik Slack memerlukan ciri Agents & AI Apps pada pelan berbayar. Penolakan pada masa panggilan (streaming_not_supported, feature_not_enabled, paid_only, …) akan diingati sepanjang hayat sambungan itu dan ditunjukkan sebagai streamingAvailable: false. Kad tugas Slack menaiki panggilan yang sama, jadi Slack yang menolak mod paparan kad itu mengekalkan strimnya dan hanya kehilangan kad itu, sekali sahaja, sepanjang hayat sambungan tersebut.

Sesuatu strim juga perlu menamakan pembaca yang ditujuinya. Slack memerlukan kedua-dua pengguna penerima dan pasukan mereka untuk membuka satu strim dalam saluran (DM tidak) dan menolak dengan missing_recipient_user_id / missing_recipient_team_id jika tidak — penolakan bagi setiap panggilan, jadi jambatan terus mencuba dan giliran itu tiba sebagai satu balasan yang disiarkan sementara itu. Penerimanya ialah sesiapa yang bertanya, diambil daripada mesej masuk (pasukan mereka, bukan pasukan apl, jadi saluran Slack Connect diselesaikan dengan betul). Bagi giliran yang tidak dimulakan oleh sesiapa dari sembang — kerja yang dimulakan dalam Control Center pada perbualan yang sudah dijambatkan — penerimanya ialah ahli yang pautannya mencipta jambatan itu; jika mereka sejak itu telah menyahpaut akaun sembang mereka, giliran itu disiarkan penuh dan bukan dialirkan.

Satu kad berkumpulan bagi setiap giliran ejen (task_display_mode: plan), dengan satu baris bagi setiap langkah. Setiap baris ialah task_update bagi id + title + status, serta details sekali sahaja apabila fikiran itu sedia. details dan output dengan id yang sama digabungkan tanpa pemisah, jadi details dihantar sekali dan output tidak pernah dialirkan. Tajuk pelan itu ialah permintaan; jawapan ialah lampiran berasingan yang kemudian membawa cebisan markdown_text.

Bahagian Kandungan
Tajuk pelan Apa yang ditanya
Baris persediaan Working on it…, kemudian Cloning …, kemudian Starting the agent… — satu baris, tajuk diganti
Baris pemikiran Thinking…, ditambah apabila ejen mula menaakul; fikiran itu ialah details baris ini, dihantar sekali apabila penaakulan selesai
Baris alat Satu bagi setiap alat (Bash which swift), id unik supaya ia duduk bersebelahan
Status Dalam proses semasa baris itu berjalan; selesai apabila baris seterusnya bermula atau giliran tamat; ralat bagi yang gagal, terganggu dan had giliran
Seruan tindakan View in Control Center sebagai baris akhir apabila giliran tamat — tiada semasa kerja masih berjalan dan tiada apabila pelayan tiada URL awam yang boleh dicapai

Apa yang tidak pernah dibawa oleh kad: keluaran alat, argumen di luar senarai izin itu, atau apa-apa yang dibaca daripada pangkalan data. Prosa penaakulan hanyalah details baris Thinking… (dihadkan pada 256 aksara), bukan badan mesej. Kad yang tidak akan menyatakan apa-apa yang baharu tidak dihantar semula. Sebutan membuka strim dengan segera supaya utas Slack tidak sunyi; giliran yang kemudiannya tidak menghasilkan teks sama sekali menamatkan kad yang sama itu dengan nota pendek dan bukan menyiarkan mesej kedua. Giliran tanpa kata pada ruang yang tidak pernah membuka strim (tiada kad, atau penstriman sudah ditolak) masih menyiarkan satu mesej yang membawa kad yang telah siap itu dan notanya.

Kad yang dialirkan dan kad yang disiarkan ialah muatan yang berbeza:

Bentuk Rupa bentuk Prosa
Dialirkan plan_update serta cebisan task_update berkunci id Rentetan biasa, dihadkan pada 256 aksara setiap cebisan
Disiarkan Blok plan yang membalut task_card berkunci task_id Teks kaya

Pengendalian kegagalan:

Situasi Tingkah laku
Penyedia menolak kad itu pada sesuatu lampiran Lampiran itu dicuba semula dengan segera tanpanya; prosa masih tiba secara langsung dan kad digugurkan sepanjang hayat sambungan tersebut
Penyedia menolak prosa itu juga Strim ditutup dan balasan disiarkan penuh
Strim terputus selepas sebahagian balasan tiba Strim ditutup dan tiada apa-apa disiarkan semula

Lihat Jambatan sembang untuk sebab muatan itu dipecahkan begini.

Kad itu terbuka apabila sebutan diterima, sebelum klon dan sebelum token pertama; giliran yang menyusul mengambil kad dan strim yang sama. Narasi selepas itu datang daripada SpaceProvisioningChanged pada bas acara domain — kemajuan yang sama yang dibaca oleh sepanduk persediaan desktop daripada baris ruang.

Keadaan persediaan Narasi
Sebutan diterima Working on it…
Langkah repo Cloning <repo>…
Langkah prCheckout Checking out the pull request in <repo>…
Langkah script Running the setup script for <repo>…
Langkah agent Setting up <agent>…
provisioning, belum ada langkah Preparing the workspace…
ready Starting the agent…
Ejen menaakul Thinking…
failed Workspace setup failed — details are in Control Center.
cancelled Workspace setup was stopped — details are in Control Center.

Narasi persediaan memerlukan keempat-empat syarat:

Syarat
Penyedia merender kad
Penstriman tersedia pada sambungan ini
Ruang itu mempunyai permintaan sembang yang sedang berjalan
Tiada kad yang sudah melaporkan giliran di sana

Permintaan itu kekal berjalan sehingga giliran bermula atau persediaan gagal. Peristiwa ready tanpa kad yang sudah terbuka ialah ruang panas dan dibiarkan senyap, dan persediaan yang tiada sesiapa dalam sembang menunggunya — perbualan yang dibuka dalam apl, perbualan terkandas yang disambung semula semasa boot — tidak menghasilkan kad sama sekali.

Produk sembang hanya menerima http(s) dalam pautan dan tidak menerima selainnya, jadi seruan tindakan tidak boleh menamakan skema desktop secara langsung.

Sifat Nilai
Laluan GET /open/workspaces/<workspaceId>/(spaces|tickets)/<id>
Asal Diperoleh daripada URL awam pelayan (ws → http, wss → https); loopback dikekalkan
Respons Halaman HTML no-store yang kecil yang menavigasi ke control-center://workspaces/<workspaceId>/(spaces|tickets)/<id> dan menunjukkan butang manual
Pengesahan Id mesti sepadan dengan [A-Za-z0-9_.-]{1,128}; apa-apa selainnya ialah 404
Akses Awam dan lengai — ia tidak membaca pangkalan data, jadi ia bukan oracle kewujudan; apl yang dibukanya melakukan kebenaran
Medan Had Nota
appName 1–35 aksara Lalai kepada Control Center · <workspace name>
botDisplayName 1–80 aksara Lalai kepada control-center
description ≤ 140 aksara
agentDescription ≤ 300 aksara Ditunjukkan di atas DM dengan bot
command ≤ 32 aksara Dinormalkan: slash di hadapan dilucutkan, ditukar kepada huruf kecil, [^a-z0-9_-] dibuang, kosong berpatah balik kepada cc
agentEnabled — Sama ada pengalaman DM/ejen didedahkan

Kotak kosong bermaksud “biarkan sahaja”, bukan “kosongkannya”. Had ini milik Slack, iaitu yang paling ketat antara produk yang dimodelkan.

Sifat Nilai
Panjang 6 aksara
Abjad 23456789ABCDEFGHJKLMNPQRSTVWXYZ (tiada 0/O, 1/I, U)
Jangka hayat 15 minit
Penggunaan Sekali
Storan Dalam memori — but semula pelayan membatalkan kod yang belum digunakan
Skop Satu ruang kerja dan satu penyedia; menjana kod baharu membatalkan kod ahli yang sebelumnya

Penebusan dipadankan tanpa mengira huruf besar atau kecil. Kod yang tidak dikenali, telah luput, milik ruang kerja asing dan penyedia yang salah semuanya gagal dengan cara yang sama, memang sengaja.

Kaedah Wayar Cara
Kod code Ahli menebus /cc link <code>
E-mel email E-mel disahkan penyedia dipadankan dengan pengguna yang sudah menjadi ahli ruang kerja

Kesemuanya berskop ruang kerja. Pelayan tidak berkeadaan, jadi setiap panggilan membawa workspace_id sendiri dalam args; penghantar menolak op berskop ruang kerja yang mengabaikannya, sebelum sebarang pangkalan data dibuka. Kelayakan bergerak masuk sahaja — bacaan status tidak pernah mengembalikannya.

Operasi Jenis Peranan minimum Kelas tindakan
chat.providers baca guest —
chat.status baca guest —
chat.connect ubah admin secretAccess, networkEgress
chat.disconnect pemusnahan admin secretAccess
chat.listUserLinks baca guest —
chat.beginUserLink ubah member —
chat.unlinkUser ubah member untuk diri sendiri, admin untuk orang lain —
chat.createApp ubah admin secretAccess, networkEgress
chat.setupLink baca admin —
chat.botProfile baca admin networkEgress
chat.updateBotProfile ubah admin networkEgress

Operasi baca mewarisi lantai guest daripada jenisnya; mutasi tanpa lantai yang jelas memerlukan member.

chat.setupLink menyusun URL penciptaan apl penyedia daripada profil bot. Ia tidak mengisytiharkan kelas tindakan kerana ia tidak membaca sebarang rahsia dan tidak mendail apa-apa — penyemak imbas pengguna sendiri membuat satu-satunya panggilan itu.

Satu pertanyaan reaktif melengkapkan permukaan itu:

Pertanyaan Jenis Memancarkan
chat.watchUserLinks pantau Senarai ahli, dihantar semula setiap kali pautan dibuat atau dibuang

Ia wujud kerana pemautan berlaku di sisi lain: ahli menaip kod sekali guna itu ke dalam bot, jadi tiada respons klien boleh membawa jawapannya kembali. Senarai ahli dalam tetapan dan dialog “pautkan akaun saya” yang terbuka kedua-duanya mengikutinya dan dialog itu bertukar kepada pengesahan sebaik sahaja pautan ahli itu sendiri tiba.

chat.beginUserLink sentiasa menjana kod untuk identiti pemanggil sendiri. chat.updateBotProfile mengembalikan remaining_step hanya apabila ada langkah yang tinggal (biasanya pemasangan semula); ketiadaannya bermakna suntingan itu sudah berkuat kuasa.

chat.providers mengembalikan satu entri bagi setiap penyedia yang ditawarkan — penerang itu serta, apabila ada, status sambungannya. Segala yang dirender oleh UI tetapan datang daripada muatan itu, sebab itulah menambah penyedia hanyalah perubahan di sisi pelayan.

Apa Di mana
Kelayakan sambungan <dataDir>/<workspaceId>/chat_credentials/<provider>.json
Persediaan berpandu yang separuh siap <dataDir>/<workspaceId>/chat_credentials/<provider>_setup.json
Fail Slack legasi <dataDir>/<workspaceId>/slack_credentials.json dan slack_app_setup.json, dibaca sekali dan dihijrahkan di tempatnya

Kelayakan berada di sisi pangkalan data ruang kerja, bukan di dalamnya: memadam ruang kerja akan membawa token sembangnya bersama dan workspace.export atau sandaran menyalin workspace.db — jadi ruang kerja yang diserahkan kepada orang lain tidak membawa token bot yang masih aktif. Penulisan bersifat atomik (fail sementara serta penamaan semula) dan diketatkan kepada pemilik sahaja.

Kedua-duanya berada dalam pangkalan data ruang kerja, yang membawa garis dasar v1 yang dipadatkan — jadi bacaan merentas ruang kerja tidak akan dikompil.

chat_space_links — satu perbualan luaran ↔ satu ruang Control Center:

Lajur Nota
id UUID v4
workspace_id Skop ruang kerja
provider ChatProvider.wire
external_team_id Pasukan Slack T…, kosong untuk penyedia tanpa konsep itu
external_channel_id Saluran Slack C…, kumpulan G…, DM D…
external_thread_id Sauh utas Slack, atau null apabila keseluruhan perbualan itu ialah sauhnya (DM bot)
cc_space_id REFERENCES spaces(id) ON DELETE CASCADE
created_by_user_id, created_at, last_activity_at

Unik pada (workspace_id, provider, external_channel_id, external_thread_id), dengan indeks separa yang menguatkuasakan perkara yang sama untuk id utas null (SQLite menganggap NULL sebagai berbeza).

chat_user_links — satu ahli luaran ↔ satu pengguna Control Center:

Lajur Nota
id UUID v4
workspace_id Skop ruang kerja
provider ChatProvider.wire
external_team_id, external_user_id Ahli Slack U…
user_id Pengguna Control Center (global, jadi tiada kunci asing)
method code atau email
linked_at

Unik pada (workspace_id, provider, external_team_id, external_user_id) dan pada (workspace_id, provider, user_id) — atribusi bernilai tunggal dalam kedua-dua arah, manakala seseorang boleh dipautkan pada beberapa penyedia.

Pautan ialah penyelesaian identiti, bukan pemberian akses: keahlian diperiksa semula pada setiap peristiwa masuk, jadi pautan kepada ahli yang sejak itu telah dibuang akan menghasilkan penolakan.

Ruang yang dijambatkan dicipta dengan SpaceKind penyedia (slack). Ia berkelakuan seperti ruang biasa yang berhadapan dengan manusia — dimaklumkan dan dibahagikan seperti topic — dan isExternalChat ialah pemeriksaan yang dilalui oleh setiap tingkah laku (pencerminan, pemberian lencana, pengekalan).

Setiap mesej yang dibawa masuk oleh jambatan membawa cap metadata['chat']:

{
"chat": {
"provider": "slack",
"teamId": "T024BE7LD",
"channelId": "C0G9QF9GW",
"threadId": "1700000000.000100",
"messageId": "1700000000.000200",
"userId": "U024BE7LH",
"userLabel": "sam"
}
}

Cap itu juga merupakan pengawal gema: cermin keluar melangkau mana-mana mesej yang membawanya, dan itulah yang menghalang mesej sembang masuk daripada disiarkan terus kembali.

Tingkah laku Butiran
Apa yang disalurkan keluar Teks ejen sahaja, serta baris status kad tugas itu. Prosa penaakulan dan keluaran alat kekal dalam Control Center
Kadens penstriman Kadarnya dihadkan kepada satu pengosongan sesaat semasa giliran berjalan; kad itu dan teks yang dijelaskannya bergerak dalam panggilan yang sama
Mesej manusia yang ditaip dalam Control Center Dicerminkan ke utas berpaut, diawali dengan nama paparan penulis
Giliran kosong Dilaporkan sebagai nota pendek (larian gagal, terganggu, atau berhenti pada had gilirannya) dan bukan kesunyian
Penyahduaan Berkunci pada id peristiwa penyedia itu sendiri; 512 yang terakhir diingati
Ejen pintu depan Perbualan yang baru dijambatkan akan membangunkan ejen CEO ruang kerja, jika tidak ejen pertamanya, jika tidak tiada sesiapa
Penamaan ruang #channel · <request> untuk utas saluran Slack, Slack DM · <request> untuk DM, tajuk dihadkan pada 48 aksara
Pengasingan kegagalan Satu peristiwa buruk tidak pernah menjatuhkan jambatan; sambungan itu terus melayani setiap perbualan lain