@integrity-labs/agt-cli 0.28.183 → 0.28.185

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -21138,6 +21138,15 @@ var SupportClient = class _SupportClient {
21138
21138
  listAudit(args = {}) {
21139
21139
  return this.get("/host/support/audit", _SupportClient.cleanQuery(args));
21140
21140
  }
21141
+ // ─────────────────────── knowledge base (ENG-7119) ───────────────────────
21142
+ // Org-lock EXEMPT: these hit /host/kb (hostAuth, NOT org-locked) — the shared,
21143
+ // published, org-neutral help. No argument names a scope.
21144
+ searchKnowledgeBase(args) {
21145
+ return this.get("/host/kb/search", _SupportClient.cleanQuery({ q: args.query, limit: args.limit }));
21146
+ }
21147
+ readKbArticle(args) {
21148
+ return this.get(`/host/kb/article/${encodeURIComponent(args.slug)}`);
21149
+ }
21141
21150
  // ─────────────────────── intake + writes (ENG-7000/7001) ───────────────────────
21142
21151
  fileSupportRequest(args) {
21143
21152
  return this.post("/host/support/file_support_request", args, true);
@@ -21145,6 +21154,10 @@ var SupportClient = class _SupportClient {
21145
21154
  fileFeatureRequest(args) {
21146
21155
  return this.post("/host/support/file_feature_request", args, true);
21147
21156
  }
21157
+ /** Report a KB gap (redacted + deduped + classified server-side). */
21158
+ requestKbArticle(args) {
21159
+ return this.post("/host/support/request_kb_article", args, true);
21160
+ }
21148
21161
  /** Propose creating an agent in the caller's OWN org (HITL-gated server-side). */
21149
21162
  createAgent(args) {
21150
21163
  return this.post("/host/support/create_agent", args, true);
@@ -21160,6 +21173,30 @@ var fileRequestSchema = external_exports.object({
21160
21173
  description: external_exports.string().min(1).describe("Full detail: what happened / what is wanted, and any reproduction steps."),
21161
21174
  provider: external_exports.string().optional().describe('Optional provider/service name when asking for a new integration (e.g. "notion").')
21162
21175
  });
21176
+ var searchKbSchema = external_exports.object({
21177
+ query: external_exports.string().trim().min(1).describe('What to look up in the knowledge base (e.g. "agent keeps restarting", "connect Slack").'),
21178
+ limit: external_exports.number().int().positive().optional().describe("Max results to return (page size, clamped server-side).")
21179
+ });
21180
+ var readKbSchema = external_exports.object({
21181
+ slug: external_exports.string().trim().min(1).describe("The kebab-case article slug returned by search_knowledge_base.")
21182
+ });
21183
+ var requestKbArticleSchema = external_exports.object({
21184
+ question: external_exports.string().trim().min(1).describe("The user question the knowledge base could not answer. Plain text; do NOT paste the conversation."),
21185
+ reason_codes: external_exports.array(
21186
+ external_exports.enum([
21187
+ "no_results",
21188
+ "low_relevance",
21189
+ "partial_answer",
21190
+ "outdated",
21191
+ "ambiguous_question",
21192
+ "out_of_scope"
21193
+ ])
21194
+ ).optional().describe("Why the KB fell short (one or more): no_results, low_relevance, partial_answer, outdated, ambiguous_question, out_of_scope."),
21195
+ tsquery: external_exports.string().trim().optional().describe("The search terms you actually queried (so curation can see what was tried)."),
21196
+ rejected_slugs: external_exports.array(
21197
+ external_exports.string().trim().regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, "must be a kebab-case article slug")
21198
+ ).optional().describe("Slugs (kebab-case) of articles you looked at but that did not answer the question.")
21199
+ });
21163
21200
  var createAgentSchema = external_exports.object({
21164
21201
  code_name: external_exports.string().regex(
21165
21202
  /^[a-z0-9]+(?:-[a-z0-9]+)*$/,
@@ -21318,6 +21355,30 @@ server.tool(
21318
21355
  }
21319
21356
  }
21320
21357
  );
21358
+ server.tool(
21359
+ "search_knowledge_base",
21360
+ "Search the Augmented knowledge base for help on a question BEFORE answering from memory or filing a request \u2014 it is the curated, up-to-date source of answers (how-tos, common fixes, FAQs). Returns ranked hits with { slug, title, tags, snippet }; call read_kb_article with a slug to get the full article. The KB is shared platform help, the same for every organization (it holds nothing org-specific), so this takes no scope. Pass { query, limit? }.",
21361
+ searchKbSchema.shape,
21362
+ async (args) => {
21363
+ try {
21364
+ return ok(await client.searchKnowledgeBase(args));
21365
+ } catch (err) {
21366
+ return fail(err);
21367
+ }
21368
+ }
21369
+ );
21370
+ server.tool(
21371
+ "read_kb_article",
21372
+ "Fetch the full published knowledge-base article for a slug returned by search_knowledge_base. Returns { article: { slug, title, body_md, tags, published_at } } or a 404 if no published article has that slug. Use the body to answer the user. Pass { slug }.",
21373
+ readKbSchema.shape,
21374
+ async (args) => {
21375
+ try {
21376
+ return ok(await client.readKbArticle(args));
21377
+ } catch (err) {
21378
+ return fail(err);
21379
+ }
21380
+ }
21381
+ );
21321
21382
  server.tool(
21322
21383
  "support_file_support_request",
21323
21384
  "File a BUG report to Augmented Team support when you hit a platform problem you cannot resolve from your own org (it goes to the Augmented Team support queue, not your org). Pass { title, description }. Returns { ok, status } - relay the outcome to the user.",
@@ -21342,6 +21403,18 @@ server.tool(
21342
21403
  }
21343
21404
  }
21344
21405
  );
21406
+ server.tool(
21407
+ "request_kb_article",
21408
+ 'Report a knowledge-base GAP after search_knowledge_base did not answer the user. Call this at most once per distinct question, AFTER searching \u2014 the server may tell you the question is already covered (status:"answerable" with a slug to read instead), needs clarifying (status:"needs_clarification" with a question to ask the user), was filed (status:"filed"), matched a known gap (status:"duplicate"), or that your org hit its daily gap limit (status:"rate_limited" with retry_after_seconds \u2014 stop filing and tell the user to try later). Provide structured context, NOT a transcript: { question, reason_codes?, tsquery? (the terms you searched), rejected_slugs? (articles that did not fit) }. Carries no scope \u2014 your org is server-derived and never stored in clear. Returns { ok, status, message }.',
21409
+ requestKbArticleSchema.shape,
21410
+ async (args) => {
21411
+ try {
21412
+ return ok(await client.requestKbArticle(args));
21413
+ } catch (err) {
21414
+ return fail(err);
21415
+ }
21416
+ }
21417
+ );
21345
21418
  server.tool(
21346
21419
  "support_create_agent",
21347
21420
  'PROPOSE creating a new agent in YOUR organization. This does NOT create the agent directly - it files a request that a human owner approves via a server-rendered diff in Slack; the agent is created (as a draft) only after approval. Use it to set up a new agent a user asked for. Returns a structured envelope: `status:"proposed"` (with request_id + expires_at - tell the user it was sent for approval and when it expires), `status:"feature_disabled"` (self-remediation writes are off for this org - tell the user to ask their operator to enable them), `status:"no_approver"` (no approval channel is configured - relay the setup hint), or `status:"rate_limited"` (too many pending - relay retry_after_seconds). Org/team are set server-side from your host - you cannot create an agent in another org. Pass { code_name (kebab-case), display_name, description?, role?, host_id?, reason? }.',
@@ -19631,6 +19631,10 @@ async function handleCallbackQuery(cb) {
19631
19631
  });
19632
19632
  return;
19633
19633
  }
19634
+ if (decoded.token.startsWith(PERF_REVIEW_TOKEN_PREFIX)) {
19635
+ await handlePerfReviewTap(cb, decoded.callbackId, decoded.token);
19636
+ return;
19637
+ }
19634
19638
  await ackCallbackQuery(cb.id, "Got it").catch(() => {
19635
19639
  });
19636
19640
  const apiCallRuntime = await Promise.resolve().then(() => (init_ask_user_runtime(), ask_user_runtime_exports));
@@ -19696,6 +19700,81 @@ async function handleCallbackQuery(cb) {
19696
19700
  void confirmationLabel;
19697
19701
  }
19698
19702
  }
19703
+ var PERF_REVIEW_TOKEN_PREFIX = "pr_";
19704
+ var PERF_REVIEW_COMMENT_TOKEN = "pr_comment";
19705
+ var PERF_REVIEW_REF_RE = /\[review:([0-9a-f-]{36})\]/;
19706
+ function perfReviewRefMarker(reviewId) {
19707
+ return `[review:${reviewId}]`;
19708
+ }
19709
+ async function handlePerfReviewTap(cb, reviewId, token) {
19710
+ if (token === PERF_REVIEW_COMMENT_TOKEN) {
19711
+ await ackCallbackQuery(cb.id, "Reply with your feedback").catch(() => {
19712
+ });
19713
+ if (cb.message) {
19714
+ try {
19715
+ const resp = await telegramApiCall(
19716
+ "sendMessage",
19717
+ {
19718
+ chat_id: cb.message.chat.id,
19719
+ text: `Reply to this message with any feedback for me.
19720
+
19721
+ ${perfReviewRefMarker(reviewId)}`,
19722
+ reply_markup: { force_reply: true, input_field_placeholder: "Your feedback\u2026" }
19723
+ },
19724
+ 5e3
19725
+ );
19726
+ if (!resp.ok) {
19727
+ process.stderr.write(
19728
+ `telegram-channel(${AGENT_CODE_NAME}): perf-review comment prompt non-ok (review_id=${reviewId}): ${resp.description ?? "unknown"}
19729
+ `
19730
+ );
19731
+ }
19732
+ } catch (err) {
19733
+ process.stderr.write(
19734
+ `telegram-channel(${AGENT_CODE_NAME}): perf-review comment prompt threw (review_id=${reviewId}): ${err.message}
19735
+ `
19736
+ );
19737
+ }
19738
+ }
19739
+ return;
19740
+ }
19741
+ const ok = await postPerfReviewResolve(reviewId, token, String(cb.from.id));
19742
+ await ackCallbackQuery(cb.id, ok ? "Recorded \u2713" : "Could not record your rating").catch(() => {
19743
+ });
19744
+ }
19745
+ async function postPerfReviewResolve(reviewId, token, respondedByUser, comment) {
19746
+ if (!channelRequestInputAvailable()) return false;
19747
+ const apiCallRuntime = await Promise.resolve().then(() => (init_ask_user_runtime(), ask_user_runtime_exports));
19748
+ const cfg = {
19749
+ apiHost: AGT_HOST,
19750
+ apiKey: AGT_API_KEY,
19751
+ agentId: AGT_AGENT_ID
19752
+ };
19753
+ try {
19754
+ const res = await apiCallRuntime.apiCall(cfg, "POST", "/host/perf-review/resolve", {
19755
+ agent_id: cfg.agentId,
19756
+ review_id: reviewId,
19757
+ token,
19758
+ ...comment !== void 0 ? { comment } : {},
19759
+ responded_by_user: respondedByUser
19760
+ });
19761
+ const j = await res.json().catch(() => ({}));
19762
+ if (!res.ok || !j.ok) {
19763
+ process.stderr.write(
19764
+ `telegram-channel(${AGENT_CODE_NAME}): /host/perf-review/resolve non-ok (review_id=${reviewId}, http=${res.status}, reason=${j.reason ?? "unknown"})
19765
+ `
19766
+ );
19767
+ return false;
19768
+ }
19769
+ return j.recorded === true;
19770
+ } catch (err) {
19771
+ process.stderr.write(
19772
+ `telegram-channel(${AGENT_CODE_NAME}): /host/perf-review/resolve threw (review_id=${reviewId}): ${err.message}
19773
+ `
19774
+ );
19775
+ return false;
19776
+ }
19777
+ }
19699
19778
  async function ackCallbackQuery(callbackQueryId, text) {
19700
19779
  try {
19701
19780
  const resp = await telegramApiCall(
@@ -19923,6 +20002,16 @@ async function pollLoop() {
19923
20002
  }
19924
20003
  const msg = update.message;
19925
20004
  if (!msg) continue;
20005
+ const perfReplyRef = typeof msg.text === "string" && msg.text.trim().length > 0 && msg.reply_to_message?.from?.is_bot === true && msg.reply_to_message?.text ? PERF_REVIEW_REF_RE.exec(msg.reply_to_message.text) : null;
20006
+ if (perfReplyRef && msg.from?.id != null) {
20007
+ await postPerfReviewResolve(
20008
+ perfReplyRef[1],
20009
+ PERF_REVIEW_COMMENT_TOKEN,
20010
+ String(msg.from.id),
20011
+ msg.text.trim()
20012
+ );
20013
+ continue;
20014
+ }
19926
20015
  const classifiedAttachments = classifyTelegramAttachments(msg);
19927
20016
  const content = typeof msg.text === "string" && msg.text.length > 0 ? msg.text : typeof msg.caption === "string" && msg.caption.length > 0 ? msg.caption : "";
19928
20017
  if (content.length === 0 && classifiedAttachments.length === 0) continue;
@@ -34,8 +34,8 @@ import {
34
34
  writeDirectChatSessionState,
35
35
  writeEgressAllowlist,
36
36
  writePersistentClaudeWrapper
37
- } from "./chunk-KE4NYCEP.js";
38
- import "./chunk-IDAJRLPK.js";
37
+ } from "./chunk-ORO4YLTN.js";
38
+ import "./chunk-ERHHYBVS.js";
39
39
  import "./chunk-XWVM4KPK.js";
40
40
  export {
41
41
  EGRESS_BASELINE_DOMAINS,
@@ -74,4 +74,4 @@ export {
74
74
  writeEgressAllowlist,
75
75
  writePersistentClaudeWrapper
76
76
  };
77
- //# sourceMappingURL=persistent-session-2TNWAAKT.js.map
77
+ //# sourceMappingURL=persistent-session-SNLNY2VB.js.map
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  paneLogPath
3
- } from "./chunk-KE4NYCEP.js";
4
- import "./chunk-IDAJRLPK.js";
3
+ } from "./chunk-ORO4YLTN.js";
4
+ import "./chunk-ERHHYBVS.js";
5
5
  import "./chunk-XWVM4KPK.js";
6
6
 
7
7
  // src/lib/responsiveness-probe.ts
@@ -304,4 +304,4 @@ export {
304
304
  readAndResetChannelDeflections,
305
305
  readAndResetChannelLaneClassifications
306
306
  };
307
- //# sourceMappingURL=responsiveness-probe-VCFRALHX.js.map
307
+ //# sourceMappingURL=responsiveness-probe-6HC3PENG.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@integrity-labs/agt-cli",
3
- "version": "0.28.183",
3
+ "version": "0.28.185",
4
4
  "description": "Augmented Team CLI — agent provisioning and management",
5
5
  "type": "module",
6
6
  "engines": {