@sentry/junior 0.85.0 → 0.87.0
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.
- package/dist/{agent-hooks-AV7CHLUO.js → agent-hooks-NWOUB3UR.js} +7 -7
- package/dist/app.js +779 -356
- package/dist/chat/conversation-privacy.d.ts +12 -2
- package/dist/chat/conversations/sql/migrations.d.ts +1 -1
- package/dist/chat/conversations/sql/store.d.ts +9 -1
- package/dist/chat/conversations/store.d.ts +13 -0
- package/dist/chat/ingress/message-changed.d.ts +2 -0
- package/dist/chat/no-reply.d.ts +7 -0
- package/dist/chat/respond.d.ts +7 -1
- package/dist/chat/runtime/reply-executor.d.ts +2 -10
- package/dist/chat/runtime/slack-runtime.d.ts +5 -4
- package/dist/chat/runtime/turn.d.ts +7 -0
- package/dist/chat/services/persist-retry.d.ts +2 -0
- package/dist/chat/services/reply-delivery-plan.d.ts +0 -4
- package/dist/chat/services/turn-session-record.d.ts +31 -2
- package/dist/chat/slack/client.d.ts +33 -2
- package/dist/chat/slack/conversation-context.d.ts +15 -0
- package/dist/chat/state/turn-session.d.ts +9 -0
- package/dist/chat/task-execution/queue.d.ts +1 -1
- package/dist/chat/task-execution/slack-work.d.ts +10 -2
- package/dist/chat/task-execution/state.d.ts +44 -4
- package/dist/chat/task-execution/store.d.ts +21 -4
- package/dist/chat/task-execution/worker.d.ts +11 -4
- package/dist/chat/tools/slack/channel-access.d.ts +29 -0
- package/dist/chat/tools/slack/thread-read.d.ts +4 -1
- package/dist/{chunk-UVNV67EC.js → chunk-2NFV5FMB.js} +4 -4
- package/dist/{chunk-QTTTRBNB.js → chunk-6I6HBOQM.js} +80 -15
- package/dist/{chunk-ENEWQMRJ.js → chunk-6O5UI3RG.js} +1 -1
- package/dist/{chunk-GY7L6VCT.js → chunk-ACJJJEGG.js} +35 -17
- package/dist/{chunk-MHEV3T2Y.js → chunk-B6FQPS7A.js} +953 -795
- package/dist/{chunk-MTE5NRPJ.js → chunk-BRSQQRG6.js} +1 -1
- package/dist/{chunk-EENOFKDN.js → chunk-ENPSU7L7.js} +165 -27
- package/dist/{chunk-RUB77TGS.js → chunk-GB5DFM4D.js} +1 -1
- package/dist/{chunk-C2PSUWK3.js → chunk-GGD6WK6V.js} +124 -25
- package/dist/{chunk-SSUEWAVS.js → chunk-JRXCSSSU.js} +19 -4
- package/dist/{chunk-DR75T7J3.js → chunk-L7OHKDOX.js} +9 -5
- package/dist/{chunk-FYPO4K7C.js → chunk-RIB3M6YA.js} +2 -2
- package/dist/{chunk-BU2AWPEN.js → chunk-ZU2ALUVQ.js} +3 -2
- package/dist/cli/chat.js +4 -4
- package/dist/cli/plugins.js +7 -7
- package/dist/cli/snapshot-warmup.js +4 -4
- package/dist/cli/upgrade.js +10 -7
- package/dist/{db-S3HYBLUS.js → db-SZVUU7RB.js} +4 -4
- package/dist/instrumentation.js +1 -1
- package/dist/nitro.js +4 -4
- package/dist/reporting/conversations.d.ts +2 -1
- package/dist/reporting.js +95 -30
- package/dist/{runner-IMQH6V2B.js → runner-DMP3IQNM.js} +27 -13
- package/package.json +6 -6
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { ConversationPrivacy } from "@/chat/conversation-privacy";
|
|
2
|
+
/** Minimal persisted-visibility port for cross-conversation read gates. */
|
|
3
|
+
export interface DestinationVisibilityReader {
|
|
4
|
+
getDestinationVisibility(args: {
|
|
5
|
+
provider: string;
|
|
6
|
+
providerDestinationId: string;
|
|
7
|
+
providerTenantId?: string;
|
|
8
|
+
}): Promise<ConversationPrivacy | undefined>;
|
|
9
|
+
}
|
|
10
|
+
export type SlackChannelReadAccess = {
|
|
11
|
+
allowed: true;
|
|
12
|
+
} | {
|
|
13
|
+
allowed: false;
|
|
14
|
+
error: string;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Decide whether the model may read Slack content from a target channel.
|
|
18
|
+
*
|
|
19
|
+
* The current conversation is always readable. Any other channel requires
|
|
20
|
+
* persisted `public` visibility in the same workspace: channel-id prefixes
|
|
21
|
+
* cannot prove a channel public (modern Slack private channels also use `C`
|
|
22
|
+
* ids), so missing or private destinations fail closed.
|
|
23
|
+
*/
|
|
24
|
+
export declare function checkSlackChannelReadAccess(args: {
|
|
25
|
+
currentChannelIds: Array<string | undefined>;
|
|
26
|
+
store?: DestinationVisibilityReader;
|
|
27
|
+
targetChannelId: string;
|
|
28
|
+
teamId: string;
|
|
29
|
+
}): Promise<SlackChannelReadAccess>;
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
import { type DestinationVisibilityReader } from "@/chat/tools/slack/channel-access";
|
|
1
2
|
import type { SlackToolContext } from "@/chat/tools/slack/context";
|
|
2
3
|
/** Create a tool that reads a Slack thread from a shared message URL or explicit coordinates. */
|
|
3
|
-
export declare function createSlackThreadReadTool(context: SlackToolContext
|
|
4
|
+
export declare function createSlackThreadReadTool(context: SlackToolContext, deps?: {
|
|
5
|
+
visibilityStore?: DestinationVisibilityReader;
|
|
6
|
+
}): import("@/chat/tools/definition").ToolDefinition<import("@sinclair/typebox").TObject<{
|
|
4
7
|
url: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
5
8
|
channel_id: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
6
9
|
ts: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createPluginLogger,
|
|
3
3
|
createPluginState
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-BRSQQRG6.js";
|
|
5
5
|
import {
|
|
6
6
|
getDb
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-6I6HBOQM.js";
|
|
8
8
|
import {
|
|
9
9
|
SANDBOX_WORKSPACE_ROOT
|
|
10
10
|
} from "./chunk-G3E7SCME.js";
|
|
@@ -13,12 +13,12 @@ import {
|
|
|
13
13
|
isConversationScopedChannel,
|
|
14
14
|
isDmChannel,
|
|
15
15
|
normalizeSlackConversationId
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-GGD6WK6V.js";
|
|
17
17
|
import {
|
|
18
18
|
botConfig,
|
|
19
19
|
completeObject,
|
|
20
20
|
embedTexts
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-ZU2ALUVQ.js";
|
|
22
22
|
import {
|
|
23
23
|
isActorUserId,
|
|
24
24
|
parseActorUserId
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
2
|
parseDestination,
|
|
3
3
|
sameDestination
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-GGD6WK6V.js";
|
|
5
5
|
import {
|
|
6
6
|
getChatConfig
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-ZU2ALUVQ.js";
|
|
8
8
|
import {
|
|
9
9
|
parseStoredSlackRequester
|
|
10
10
|
} from "./chunk-IXTBFABZ.js";
|
|
11
11
|
|
|
12
12
|
// src/chat/conversations/sql/store.ts
|
|
13
13
|
import { randomUUID } from "crypto";
|
|
14
|
-
import { asc, desc, eq, sql as sql2 } from "drizzle-orm";
|
|
14
|
+
import { and, asc, desc, eq, sql as sql2 } from "drizzle-orm";
|
|
15
15
|
|
|
16
16
|
// src/chat/conversations/sql/migrations.ts
|
|
17
17
|
import { createHash } from "crypto";
|
|
@@ -298,8 +298,20 @@ CREATE INDEX IF NOT EXISTS junior_conversations_origin_idx
|
|
|
298
298
|
ON junior_conversations (origin_type, origin_id, last_activity_at DESC)
|
|
299
299
|
`
|
|
300
300
|
];
|
|
301
|
+
var destinationVisibilityBackfillStatements = [
|
|
302
|
+
`
|
|
303
|
+
UPDATE junior_destinations
|
|
304
|
+
SET visibility = 'private'
|
|
305
|
+
WHERE provider = 'slack'
|
|
306
|
+
AND visibility = 'public'
|
|
307
|
+
`
|
|
308
|
+
];
|
|
301
309
|
var migrations = [
|
|
302
|
-
defineMigration("0001_conversation_core", coreMetadataStatements)
|
|
310
|
+
defineMigration("0001_conversation_core", coreMetadataStatements),
|
|
311
|
+
defineMigration(
|
|
312
|
+
"0002_slack_destination_visibility_backfill",
|
|
313
|
+
destinationVisibilityBackfillStatements
|
|
314
|
+
)
|
|
303
315
|
];
|
|
304
316
|
function parseStoredMigrationRecord(value) {
|
|
305
317
|
return migrationRecordSchema.parse(value);
|
|
@@ -436,13 +448,13 @@ function destinationUpsertFromDestination(args) {
|
|
|
436
448
|
if (destination.platform === "slack") {
|
|
437
449
|
const channelId = destination.channelId;
|
|
438
450
|
const channelKind = channelId.startsWith("D") ? "dm" : channelId.startsWith("G") ? "group" : "channel";
|
|
439
|
-
const visibility = channelId.startsWith("D") ? "direct" : channelId.startsWith("G") ? "private" : "public";
|
|
440
451
|
return {
|
|
441
452
|
kind: channelKind,
|
|
442
453
|
provider: "slack",
|
|
443
454
|
providerTenantId: destination.teamId,
|
|
444
455
|
providerDestinationId: channelId,
|
|
445
|
-
visibility,
|
|
456
|
+
refreshVisibility: args.visibility !== void 0,
|
|
457
|
+
visibility: args.visibility ?? "private",
|
|
446
458
|
...args.channelName ? { displayName: args.channelName } : {},
|
|
447
459
|
metadata: { platform: "slack" }
|
|
448
460
|
};
|
|
@@ -452,6 +464,7 @@ function destinationUpsertFromDestination(args) {
|
|
|
452
464
|
provider: "local",
|
|
453
465
|
providerTenantId: localWorkspaceFromConversationId(destination.conversationId) ?? localWorkspaceFromConversationId(args.conversationId ?? ""),
|
|
454
466
|
providerDestinationId: destination.conversationId,
|
|
467
|
+
refreshVisibility: true,
|
|
455
468
|
visibility: "direct",
|
|
456
469
|
metadata: { platform: "local" }
|
|
457
470
|
};
|
|
@@ -462,7 +475,15 @@ function executionStatusFromValue(value) {
|
|
|
462
475
|
}
|
|
463
476
|
throw new Error("Conversation record execution status is invalid");
|
|
464
477
|
}
|
|
465
|
-
function
|
|
478
|
+
function privacyFromRow(row) {
|
|
479
|
+
if (row.destinationVisibility === null) {
|
|
480
|
+
return void 0;
|
|
481
|
+
}
|
|
482
|
+
return row.destinationVisibility === "public" ? "public" : "private";
|
|
483
|
+
}
|
|
484
|
+
function conversationFromRow(readRow) {
|
|
485
|
+
const row = readRow.conversation;
|
|
486
|
+
const visibility = privacyFromRow(readRow);
|
|
466
487
|
if (row.schemaVersion !== 1) {
|
|
467
488
|
throw new Error("Conversation record schema version is invalid");
|
|
468
489
|
}
|
|
@@ -496,7 +517,8 @@ function conversationFromRow(row) {
|
|
|
496
517
|
...requester ? { requester } : {},
|
|
497
518
|
...row.channelName ? { channelName: row.channelName } : {},
|
|
498
519
|
...source ? { source } : {},
|
|
499
|
-
...row.title ? { title: row.title } : {}
|
|
520
|
+
...row.title ? { title: row.title } : {},
|
|
521
|
+
...visibility ? { visibility } : {}
|
|
500
522
|
};
|
|
501
523
|
}
|
|
502
524
|
function emptyConversation(args) {
|
|
@@ -572,9 +594,10 @@ var SqlStore = class {
|
|
|
572
594
|
nowMs,
|
|
573
595
|
source: args.source
|
|
574
596
|
});
|
|
597
|
+
const { visibility: _persisted, ...currentWithoutVisibility } = current2;
|
|
575
598
|
await this.upsertConversation({
|
|
576
599
|
conversation: {
|
|
577
|
-
...
|
|
600
|
+
...currentWithoutVisibility,
|
|
578
601
|
destination: current2.destination ?? args.destination,
|
|
579
602
|
source: current2.source ?? args.source,
|
|
580
603
|
channelName: current2.channelName ?? args.channelName,
|
|
@@ -585,7 +608,8 @@ var SqlStore = class {
|
|
|
585
608
|
execution: {
|
|
586
609
|
...current2.execution,
|
|
587
610
|
updatedAtMs: current2.execution.updatedAtMs ?? nowMs
|
|
588
|
-
}
|
|
611
|
+
},
|
|
612
|
+
...args.visibility ? { visibility: args.visibility } : {}
|
|
589
613
|
}
|
|
590
614
|
});
|
|
591
615
|
});
|
|
@@ -604,13 +628,15 @@ var SqlStore = class {
|
|
|
604
628
|
...args.requester ? { requester: args.requester } : {},
|
|
605
629
|
...args.source ? { source: args.source } : {},
|
|
606
630
|
...args.title ? { title: args.title } : {},
|
|
631
|
+
...args.visibility ? { visibility: args.visibility } : {},
|
|
607
632
|
execution: args.execution
|
|
608
633
|
}
|
|
609
634
|
});
|
|
610
635
|
});
|
|
611
636
|
}
|
|
612
637
|
/** Copy one conversation record into SQL during backfill. */
|
|
613
|
-
async backfillConversation(
|
|
638
|
+
async backfillConversation(sourceConversation) {
|
|
639
|
+
const { visibility: _visibility, ...conversation } = sourceConversation;
|
|
614
640
|
await this.withConversationMutation(
|
|
615
641
|
conversation.conversationId,
|
|
616
642
|
async () => {
|
|
@@ -646,7 +672,13 @@ var SqlStore = class {
|
|
|
646
672
|
);
|
|
647
673
|
}
|
|
648
674
|
async listByActivity(args = {}) {
|
|
649
|
-
const rows = await this.executor.db().select(
|
|
675
|
+
const rows = await this.executor.db().select({
|
|
676
|
+
conversation: juniorConversations,
|
|
677
|
+
destinationVisibility: juniorDestinations.visibility
|
|
678
|
+
}).from(juniorConversations).leftJoin(
|
|
679
|
+
juniorDestinations,
|
|
680
|
+
eq(juniorDestinations.id, juniorConversations.destinationId)
|
|
681
|
+
).orderBy(
|
|
650
682
|
desc(juniorConversations.lastActivityAt),
|
|
651
683
|
asc(juniorConversations.conversationId)
|
|
652
684
|
).limit(Math.max(0, args.limit ?? 1e4)).offset(Math.max(0, args.offset ?? 0));
|
|
@@ -656,6 +688,28 @@ var SqlStore = class {
|
|
|
656
688
|
}
|
|
657
689
|
return conversations;
|
|
658
690
|
}
|
|
691
|
+
async getDestinationVisibility(args) {
|
|
692
|
+
const rows = await this.executor.db().select({
|
|
693
|
+
visibility: juniorDestinations.visibility
|
|
694
|
+
}).from(juniorDestinations).where(
|
|
695
|
+
and(
|
|
696
|
+
eq(juniorDestinations.provider, args.provider),
|
|
697
|
+
eq(
|
|
698
|
+
juniorDestinations.providerTenantId,
|
|
699
|
+
tenantId(args.providerTenantId)
|
|
700
|
+
),
|
|
701
|
+
eq(
|
|
702
|
+
juniorDestinations.providerDestinationId,
|
|
703
|
+
args.providerDestinationId
|
|
704
|
+
)
|
|
705
|
+
)
|
|
706
|
+
);
|
|
707
|
+
const row = rows[0];
|
|
708
|
+
if (!row) {
|
|
709
|
+
return void 0;
|
|
710
|
+
}
|
|
711
|
+
return row.visibility === "public" ? "public" : "private";
|
|
712
|
+
}
|
|
659
713
|
/** Serialize all durable mutations for one conversation inside a SQL transaction. */
|
|
660
714
|
async withConversationMutation(conversationId, callback) {
|
|
661
715
|
return await this.executor.withLock(
|
|
@@ -664,7 +718,13 @@ var SqlStore = class {
|
|
|
664
718
|
);
|
|
665
719
|
}
|
|
666
720
|
async readConversationRow(conversationId) {
|
|
667
|
-
const rows = await this.executor.db().select(
|
|
721
|
+
const rows = await this.executor.db().select({
|
|
722
|
+
conversation: juniorConversations,
|
|
723
|
+
destinationVisibility: juniorDestinations.visibility
|
|
724
|
+
}).from(juniorConversations).leftJoin(
|
|
725
|
+
juniorDestinations,
|
|
726
|
+
eq(juniorDestinations.id, juniorConversations.destinationId)
|
|
727
|
+
).where(eq(juniorConversations.conversationId, conversationId));
|
|
668
728
|
return rows[0];
|
|
669
729
|
}
|
|
670
730
|
/** Upsert the conversation row while preserving previously discovered nullable metadata fields. */
|
|
@@ -677,7 +737,8 @@ var SqlStore = class {
|
|
|
677
737
|
destinationUpsertFromDestination({
|
|
678
738
|
channelName: conversation.channelName,
|
|
679
739
|
conversationId: conversation.conversationId,
|
|
680
|
-
destination: conversation.destination
|
|
740
|
+
destination: conversation.destination,
|
|
741
|
+
...conversation.visibility ? { visibility: conversation.visibility } : {}
|
|
681
742
|
}),
|
|
682
743
|
conversation.updatedAtMs
|
|
683
744
|
);
|
|
@@ -779,6 +840,7 @@ var SqlStore = class {
|
|
|
779
840
|
if (!destination) {
|
|
780
841
|
return void 0;
|
|
781
842
|
}
|
|
843
|
+
const visibilityUpdate = destination.refreshVisibility ? sql2`excluded.visibility` : juniorDestinations.visibility;
|
|
782
844
|
const rows = await this.executor.db().insert(juniorDestinations).values({
|
|
783
845
|
id: randomUUID(),
|
|
784
846
|
provider: destination.provider,
|
|
@@ -800,7 +862,10 @@ var SqlStore = class {
|
|
|
800
862
|
set: {
|
|
801
863
|
kind: sql2`excluded.kind`,
|
|
802
864
|
displayName: sql2`coalesce(excluded.display_name, ${juniorDestinations.displayName})`,
|
|
803
|
-
|
|
865
|
+
// Signal-less writes insert as private but must not clobber an
|
|
866
|
+
// existing public/private value. Live source signals refresh this
|
|
867
|
+
// field so converted channels converge on the next message.
|
|
868
|
+
visibility: visibilityUpdate,
|
|
804
869
|
metadata: sql2`coalesce(excluded.metadata_json, ${juniorDestinations.metadata})`,
|
|
805
870
|
updatedAt: sql2`excluded.updated_at`
|
|
806
871
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getConversationStore
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-6I6HBOQM.js";
|
|
4
4
|
import {
|
|
5
5
|
SANDBOX_DATA_ROOT,
|
|
6
6
|
SANDBOX_WORKSPACE_ROOT,
|
|
@@ -9,16 +9,16 @@ import {
|
|
|
9
9
|
import {
|
|
10
10
|
getConnectedStateContext,
|
|
11
11
|
getStateAdapter
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-GB5DFM4D.js";
|
|
13
13
|
import {
|
|
14
14
|
parseDestination
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-GGD6WK6V.js";
|
|
16
16
|
import {
|
|
17
17
|
TURN_CONTEXT_TAG,
|
|
18
18
|
botConfig,
|
|
19
19
|
escapeXml,
|
|
20
20
|
getChatConfig
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-ZU2ALUVQ.js";
|
|
22
22
|
import {
|
|
23
23
|
parseRequester,
|
|
24
24
|
storedSlackRequesterSchema,
|
|
@@ -659,16 +659,28 @@ async function commitMessages(args) {
|
|
|
659
659
|
};
|
|
660
660
|
}
|
|
661
661
|
|
|
662
|
-
// src/chat/prompt.ts
|
|
663
|
-
import fs from "fs";
|
|
664
|
-
import path from "path";
|
|
665
|
-
|
|
666
662
|
// src/chat/interruption-marker.ts
|
|
667
663
|
var INTERRUPTED_MARKER = "\n\n[Response interrupted before completion]";
|
|
668
664
|
function getInterruptionMarker() {
|
|
669
665
|
return INTERRUPTED_MARKER;
|
|
670
666
|
}
|
|
671
667
|
|
|
668
|
+
// src/chat/prompt.ts
|
|
669
|
+
import fs from "fs";
|
|
670
|
+
import path from "path";
|
|
671
|
+
|
|
672
|
+
// src/chat/no-reply.ts
|
|
673
|
+
var NO_REPLY_MARKER = "[[NO_REPLY]]";
|
|
674
|
+
function isNoReplyMarker(text) {
|
|
675
|
+
return text.trim() === NO_REPLY_MARKER;
|
|
676
|
+
}
|
|
677
|
+
function containsNoReplyMarker(text) {
|
|
678
|
+
return text.includes(NO_REPLY_MARKER);
|
|
679
|
+
}
|
|
680
|
+
function stripNoReplyMarker(text) {
|
|
681
|
+
return text.replaceAll(NO_REPLY_MARKER, "").trim();
|
|
682
|
+
}
|
|
683
|
+
|
|
672
684
|
// src/chat/slack/status-format.ts
|
|
673
685
|
var SLACK_STATUS_MAX_LENGTH = 50;
|
|
674
686
|
function truncateStatusText(text) {
|
|
@@ -1360,12 +1372,10 @@ var CONVERSATION_RULES = [
|
|
|
1360
1372
|
"- Runtime owns continuation and authorization notices; on resumed turns, answer with the final requested content only."
|
|
1361
1373
|
];
|
|
1362
1374
|
var SLACK_ACTION_RULES = [
|
|
1363
|
-
"-
|
|
1364
|
-
"- Use
|
|
1365
|
-
"-
|
|
1366
|
-
|
|
1367
|
-
"- Do not claim an attachment, canvas, channel post, list update, or reaction succeeded unless the tool returned success this turn; when it did, include any link the tool returned.",
|
|
1368
|
-
"- Do not use reactions as progress indicators."
|
|
1375
|
+
"- Slack tools target the current runtime context; if the requested Slack target differs, explain the limitation instead of calling the tool.",
|
|
1376
|
+
"- Use channel-post and emoji-reaction tools only for explicit user-requested Slack side effects.",
|
|
1377
|
+
"- Ambient reaction requests target the current inbound message; do not ask for a message reference.",
|
|
1378
|
+
`- Side-effect-only completion for channel posts or reactions: call the requested tool first; if it succeeds and fully satisfies the request, final message must be exactly ${NO_REPLY_MARKER}.`
|
|
1369
1379
|
];
|
|
1370
1380
|
var SAFETY_RULES = [
|
|
1371
1381
|
"- Stay within the user's request and the runtime's available capabilities; do not pursue independent goals, persistence, replication, credential gathering, or access expansion.",
|
|
@@ -1416,7 +1426,7 @@ function buildOutputSection(platform) {
|
|
|
1416
1426
|
"- Use Slack-flavored Markdown: **bold** section labels, `code`, [text](url) links, bullet lists, and fenced code blocks. No hash-prefixed headings and no tables. When the answer primarily lists several URLs, show each URL bare instead of as a labeled link.",
|
|
1417
1427
|
"- Keep replies brief and scannable; use bullets or short code blocks when helpful, and one compact thread reply when it fits.",
|
|
1418
1428
|
"- When a research or document-style answer would benefit from continuation, multiple sections, or future reference value, create a Slack canvas and keep the thread reply to one or two short sentences plus the link; do not recap the canvas contents.",
|
|
1419
|
-
"-
|
|
1429
|
+
"- End every turn with a final user-facing markdown response unless the Slack action rules allow a side-effect-only completion.",
|
|
1420
1430
|
"</output>"
|
|
1421
1431
|
].join("\n");
|
|
1422
1432
|
}
|
|
@@ -1847,7 +1857,8 @@ async function recordConversationActivityMetadata(args) {
|
|
|
1847
1857
|
destination: args.summary.destination,
|
|
1848
1858
|
nowMs: args.nowMs,
|
|
1849
1859
|
requester: sessionLogRequester(args.summary.requester),
|
|
1850
|
-
source
|
|
1860
|
+
source,
|
|
1861
|
+
visibility: args.destinationVisibility
|
|
1851
1862
|
});
|
|
1852
1863
|
await conversationStore.recordExecution({
|
|
1853
1864
|
channelName: args.summary.channelName,
|
|
@@ -1858,7 +1869,8 @@ async function recordConversationActivityMetadata(args) {
|
|
|
1858
1869
|
lastActivityAtMs: args.summary.updatedAtMs,
|
|
1859
1870
|
requester: sessionLogRequester(args.summary.requester),
|
|
1860
1871
|
source,
|
|
1861
|
-
updatedAtMs: args.nowMs
|
|
1872
|
+
updatedAtMs: args.nowMs,
|
|
1873
|
+
visibility: args.destinationVisibility
|
|
1862
1874
|
});
|
|
1863
1875
|
} catch (error) {
|
|
1864
1876
|
logWarn(
|
|
@@ -1998,6 +2010,7 @@ async function setStoredRecord(args) {
|
|
|
1998
2010
|
await appendAgentTurnSessionSummary(summary, args.ttlMs);
|
|
1999
2011
|
await recordConversationActivityMetadata({
|
|
2000
2012
|
conversationStore: args.conversationStore,
|
|
2013
|
+
destinationVisibility: args.destinationVisibility,
|
|
2001
2014
|
nowMs: Date.now(),
|
|
2002
2015
|
summary
|
|
2003
2016
|
});
|
|
@@ -2054,6 +2067,7 @@ async function upsertAgentTurnSessionRecord(args) {
|
|
|
2054
2067
|
});
|
|
2055
2068
|
return await setStoredRecord({
|
|
2056
2069
|
conversationStore: args.conversationStore,
|
|
2070
|
+
destinationVisibility: args.destinationVisibility,
|
|
2057
2071
|
piMessages: args.piMessages,
|
|
2058
2072
|
ttlMs,
|
|
2059
2073
|
record: buildStoredRecord({
|
|
@@ -2118,6 +2132,7 @@ async function recordAgentTurnSessionSummary(args) {
|
|
|
2118
2132
|
await appendAgentTurnSessionSummary(summary, ttlMs);
|
|
2119
2133
|
await recordConversationActivityMetadata({
|
|
2120
2134
|
conversationStore: args.conversationStore,
|
|
2135
|
+
destinationVisibility: args.destinationVisibility,
|
|
2121
2136
|
nowMs,
|
|
2122
2137
|
summary
|
|
2123
2138
|
});
|
|
@@ -2180,6 +2195,9 @@ async function failAgentTurnSessionRecord(args) {
|
|
|
2180
2195
|
}
|
|
2181
2196
|
|
|
2182
2197
|
export {
|
|
2198
|
+
isNoReplyMarker,
|
|
2199
|
+
containsNoReplyMarker,
|
|
2200
|
+
stripNoReplyMarker,
|
|
2183
2201
|
getInterruptionMarker,
|
|
2184
2202
|
truncateStatusText,
|
|
2185
2203
|
normalizeSlackStatusText,
|