instar 0.28.50 → 0.28.51
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/cli.js +0 -0
- package/dist/commands/server.d.ts.map +1 -1
- package/dist/commands/server.js +61 -31
- package/dist/commands/server.js.map +1 -1
- package/dist/core/InputGuard.d.ts +29 -3
- package/dist/core/InputGuard.d.ts.map +1 -1
- package/dist/core/InputGuard.js +73 -45
- package/dist/core/InputGuard.js.map +1 -1
- package/dist/messaging/shared/isSystemOrProxyMessage.d.ts +41 -0
- package/dist/messaging/shared/isSystemOrProxyMessage.d.ts.map +1 -0
- package/dist/messaging/shared/isSystemOrProxyMessage.js +64 -0
- package/dist/messaging/shared/isSystemOrProxyMessage.js.map +1 -0
- package/dist/monitoring/PresenceProxy.d.ts +3 -1
- package/dist/monitoring/PresenceProxy.d.ts.map +1 -1
- package/dist/monitoring/PresenceProxy.js +5 -16
- package/dist/monitoring/PresenceProxy.js.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +6 -6
- package/upgrades/0.28.51.md +31 -0
- package/upgrades/0.28.52.md +82 -0
- package/upgrades/side-effects/0.28.50.md +104 -0
- package/upgrades/side-effects/0.28.51.md +145 -0
- package/upgrades/side-effects/0.28.52.md +276 -0
- package/upgrades/0.28.48.md +0 -52
- package/upgrades/NEXT.md +0 -53
package/dist/cli.js
CHANGED
|
File without changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA2PH,UAAU,YAAY;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;2DACuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AA81CD,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA+
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA2PH,UAAU,YAAY;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;2DACuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AA81CD,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA+0ItE;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAsDzE;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAuD5E"}
|
package/dist/commands/server.js
CHANGED
|
@@ -1761,27 +1761,9 @@ export async function startServer(options) {
|
|
|
1761
1761
|
}
|
|
1762
1762
|
}
|
|
1763
1763
|
const sessionManager = new SessionManager(config.sessions, state);
|
|
1764
|
-
// Input Guard
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
const anthropicKey = process.env['ANTHROPIC_API_KEY']?.trim();
|
|
1768
|
-
const { InputGuard } = await import('../core/InputGuard.js');
|
|
1769
|
-
const inputGuard = new InputGuard({
|
|
1770
|
-
config: {
|
|
1771
|
-
enabled: true,
|
|
1772
|
-
provenanceCheck: guardConfig.provenanceCheck ?? true,
|
|
1773
|
-
injectionPatterns: guardConfig.injectionPatterns ?? true,
|
|
1774
|
-
topicCoherenceReview: guardConfig.topicCoherenceReview ?? true,
|
|
1775
|
-
action: guardConfig.action ?? 'warn',
|
|
1776
|
-
reviewTimeout: guardConfig.reviewTimeout ?? 3000,
|
|
1777
|
-
},
|
|
1778
|
-
stateDir: config.stateDir,
|
|
1779
|
-
apiKey: anthropicKey,
|
|
1780
|
-
});
|
|
1781
|
-
const registryPath = path.join(config.stateDir, 'topic-session-registry.json');
|
|
1782
|
-
sessionManager.setInputGuard(inputGuard, registryPath);
|
|
1783
|
-
console.log(pc.green(` Input Guard: enabled (action: ${guardConfig.action ?? 'warn'})`));
|
|
1784
|
-
}
|
|
1764
|
+
// Input Guard is constructed later (after sharedIntelligence is available)
|
|
1765
|
+
// so the topic coherence reviewer can route through the IntelligenceProvider
|
|
1766
|
+
// abstraction instead of calling Anthropic directly.
|
|
1785
1767
|
// TopicResumeMap: persist Claude session UUIDs across session restarts.
|
|
1786
1768
|
// When a session is killed/restarted, we save its UUID so the next spawn
|
|
1787
1769
|
// can use --resume to reattach to the existing conversation context.
|
|
@@ -1837,11 +1819,54 @@ export async function startServer(options) {
|
|
|
1837
1819
|
}
|
|
1838
1820
|
else {
|
|
1839
1821
|
console.log(pc.yellow(' Intelligence: none (no Claude CLI, no API key) — LLM-gated features degraded'));
|
|
1822
|
+
// Visible degradation — every downstream LLM-gated feature depends on this.
|
|
1823
|
+
// The DegradationReporter routes to console, disk, Telegram alert, and feedback.
|
|
1824
|
+
// Keep the externally-rendered impact string generic; the detailed
|
|
1825
|
+
// capability-down enumeration (tone gate, input guard, coherence gate, stall
|
|
1826
|
+
// triage, job reflection) stays in the yellow console line above and the
|
|
1827
|
+
// local degradations.json log. We don't broadcast a "which defenses are down"
|
|
1828
|
+
// checklist to Telegram/feedback channels.
|
|
1829
|
+
const { DegradationReporter } = await import('../monitoring/DegradationReporter.js');
|
|
1830
|
+
DegradationReporter.getInstance().report({
|
|
1831
|
+
feature: 'SharedIntelligenceProvider',
|
|
1832
|
+
primary: 'Shared LLM provider (Claude CLI subscription by default, Anthropic API opt-in)',
|
|
1833
|
+
fallback: 'Heuristic-only operation for LLM-gated features',
|
|
1834
|
+
reason: 'No LLM transport configured on this machine (see local startup logs for detail).',
|
|
1835
|
+
impact: 'LLM-gated features degraded; defense-in-depth reduced. See local logs for the affected feature list.',
|
|
1836
|
+
});
|
|
1840
1837
|
}
|
|
1841
1838
|
// Wire intelligence into git sync for LLM conflict resolution (Tier 1 → 2)
|
|
1842
1839
|
if (gitSync && sharedIntelligence) {
|
|
1843
1840
|
gitSync.setIntelligence(sharedIntelligence);
|
|
1844
1841
|
}
|
|
1842
|
+
// Input Guard — cross-topic injection defense (Layer 1 + 1.5 + 2).
|
|
1843
|
+
// Constructed AFTER sharedIntelligence so the topic-coherence reviewer routes
|
|
1844
|
+
// through the IntelligenceProvider (subscription-first). InputGuard no longer
|
|
1845
|
+
// carries a direct Anthropic API path — all LLM usage flows through the shared
|
|
1846
|
+
// provider abstraction, enforcing the subscription-first principle at the
|
|
1847
|
+
// single provider-selection layer rather than in each consumer.
|
|
1848
|
+
if (config.inputGuard?.enabled !== false) {
|
|
1849
|
+
const guardConfig = config.inputGuard ?? { enabled: true };
|
|
1850
|
+
const { InputGuard } = await import('../core/InputGuard.js');
|
|
1851
|
+
const inputGuard = new InputGuard({
|
|
1852
|
+
config: {
|
|
1853
|
+
enabled: true,
|
|
1854
|
+
provenanceCheck: guardConfig.provenanceCheck ?? true,
|
|
1855
|
+
injectionPatterns: guardConfig.injectionPatterns ?? true,
|
|
1856
|
+
topicCoherenceReview: guardConfig.topicCoherenceReview ?? true,
|
|
1857
|
+
action: guardConfig.action ?? 'warn',
|
|
1858
|
+
reviewTimeout: guardConfig.reviewTimeout ?? 3000,
|
|
1859
|
+
},
|
|
1860
|
+
stateDir: config.stateDir,
|
|
1861
|
+
intelligence: sharedIntelligence,
|
|
1862
|
+
});
|
|
1863
|
+
const registryPath = path.join(config.stateDir, 'topic-session-registry.json');
|
|
1864
|
+
sessionManager.setInputGuard(inputGuard, registryPath);
|
|
1865
|
+
const reviewBackend = sharedIntelligence
|
|
1866
|
+
? 'via shared IntelligenceProvider'
|
|
1867
|
+
: 'provenance + patterns only (no LLM review)';
|
|
1868
|
+
console.log(pc.green(` Input Guard: enabled (action: ${guardConfig.action ?? 'warn'}, ${reviewBackend})`));
|
|
1869
|
+
}
|
|
1845
1870
|
let relationships;
|
|
1846
1871
|
if (config.relationships) {
|
|
1847
1872
|
// Wire LLM intelligence for identity resolution.
|
|
@@ -3840,6 +3865,7 @@ export async function startServer(options) {
|
|
|
3840
3865
|
// (3) "continue where you left off" tells the agent not to re-ask or
|
|
3841
3866
|
// re-litigate, just pick up.
|
|
3842
3867
|
const COMPACTION_RESUME_PROMPT = 'Your session just went through context compaction. Read the recent messages in this topic to re-orient, briefly let the user know compaction occurred, then continue where you left off.';
|
|
3868
|
+
const { isSystemOrProxyMessage, findLastRealMessage } = await import('../messaging/shared/isSystemOrProxyMessage.js');
|
|
3843
3869
|
const recoverCompactedSession = async (sessionName, triggerLabel) => {
|
|
3844
3870
|
if (!sessionManager.isSessionAlive(sessionName))
|
|
3845
3871
|
return false;
|
|
@@ -3847,9 +3873,15 @@ export async function startServer(options) {
|
|
|
3847
3873
|
if (telegram) {
|
|
3848
3874
|
const topicId = telegram.getTopicForSession(sessionName);
|
|
3849
3875
|
if (topicId) {
|
|
3850
|
-
|
|
3851
|
-
|
|
3852
|
-
|
|
3876
|
+
// Walk history backward, skipping PresenceProxy standby messages and
|
|
3877
|
+
// server-emitted delivery/lifecycle acks. Those are from-agent but
|
|
3878
|
+
// they are NOT real responses — treating them as "agent answered"
|
|
3879
|
+
// is what let this recovery path silently decline for 15 minutes
|
|
3880
|
+
// while the user's question sat unanswered. See
|
|
3881
|
+
// isSystemOrProxyMessage / findLastRealMessage for the canonical filter.
|
|
3882
|
+
const history = telegram.getTopicHistory(topicId, 20);
|
|
3883
|
+
const lastReal = findLastRealMessage(history);
|
|
3884
|
+
if (lastReal?.fromUser) {
|
|
3853
3885
|
console.log(`[CompactionResume] (${triggerLabel}) topic ${topicId} session "${sessionName}" has unanswered message — recovering`);
|
|
3854
3886
|
// Direct injection with topic tag so InputGuard accepts it.
|
|
3855
3887
|
const tagged = `[telegram:${topicId}] ${COMPACTION_RESUME_PROMPT}`;
|
|
@@ -4102,7 +4134,10 @@ export async function startServer(options) {
|
|
|
4102
4134
|
const { execSync: shellExecSync } = await import('child_process');
|
|
4103
4135
|
const messagesLogPath = path.join(config.stateDir, 'telegram-messages.jsonl');
|
|
4104
4136
|
const slackMessagesLogPath = path.join(config.stateDir, 'slack-messages.jsonl');
|
|
4105
|
-
// Shared helper: check a messages log file for agent responses after a timestamp
|
|
4137
|
+
// Shared helper: check a messages log file for agent responses after a timestamp.
|
|
4138
|
+
// System/proxy-message filtering is delegated to isSystemOrProxyMessage so all
|
|
4139
|
+
// three callsites (this one, PresenceProxy.isSystemMessage, and the compaction
|
|
4140
|
+
// recoverFn) stay in sync.
|
|
4106
4141
|
const checkLogForAgentResponse = (logPath, topicId, sinceIso) => {
|
|
4107
4142
|
try {
|
|
4108
4143
|
const content = fs.readFileSync(logPath, 'utf-8');
|
|
@@ -4115,12 +4150,7 @@ export async function startServer(options) {
|
|
|
4115
4150
|
const matchesTopic = msg.topicId === topicId
|
|
4116
4151
|
|| (topicId < 0 && msg.channelId && slackChannelToSyntheticId(String(msg.channelId)) === topicId);
|
|
4117
4152
|
if (matchesTopic && !msg.fromUser && msg.timestamp > sinceIso) {
|
|
4118
|
-
|
|
4119
|
-
const isSystem = t === '✓ Delivered' || t.startsWith('✓ Delivered')
|
|
4120
|
-
|| t.startsWith('🔄 Session restarting') || t === 'Session respawned.'
|
|
4121
|
-
|| t === 'Session terminated.' || t.startsWith('Send a new message to start')
|
|
4122
|
-
|| t.startsWith('🔭');
|
|
4123
|
-
if (!isSystem)
|
|
4153
|
+
if (!isSystemOrProxyMessage(msg.text))
|
|
4124
4154
|
return true;
|
|
4125
4155
|
}
|
|
4126
4156
|
}
|