@agent-native/core 0.153.4 → 0.153.5
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/corpus/templates/analytics/actions/account-deep-dive.ts +1 -0
- package/corpus/templates/analytics/actions/bigquery-query.ts +1 -0
- package/corpus/templates/analytics/actions/bigquery.ts +1 -0
- package/corpus/templates/analytics/actions/content-calendar-schema.ts +1 -0
- package/corpus/templates/analytics/actions/content-calendar.ts +1 -0
- package/corpus/templates/analytics/actions/gcloud.ts +1 -0
- package/corpus/templates/analytics/actions/get-data-program.ts +1 -0
- package/corpus/templates/analytics/actions/get-error-issue.ts +1 -0
- package/corpus/templates/analytics/actions/get-monitor-stats.ts +1 -0
- package/corpus/templates/analytics/actions/get-monitor.ts +1 -0
- package/corpus/templates/analytics/actions/get-session-replay-events.ts +1 -0
- package/corpus/templates/analytics/actions/get-session-replay-summary.ts +1 -0
- package/corpus/templates/analytics/actions/get-session-replay-timeline.ts +1 -0
- package/corpus/templates/analytics/actions/gong-calls.ts +1 -0
- package/corpus/templates/analytics/actions/gong-native-insights.ts +1 -0
- package/corpus/templates/analytics/actions/grafana.ts +1 -0
- package/corpus/templates/analytics/actions/hubspot-deals.ts +1 -0
- package/corpus/templates/analytics/actions/hubspot-metrics.ts +1 -0
- package/corpus/templates/analytics/actions/hubspot-pipelines.ts +1 -0
- package/corpus/templates/analytics/actions/hubspot-records.ts +1 -0
- package/corpus/templates/analytics/actions/jira-search.ts +1 -0
- package/corpus/templates/analytics/actions/jira.ts +1 -0
- package/corpus/templates/analytics/actions/list-error-issues.ts +1 -0
- package/corpus/templates/analytics/actions/list-monitors.ts +1 -0
- package/corpus/templates/analytics/actions/list-session-recordings.ts +1 -0
- package/corpus/templates/analytics/actions/match-error-issues.ts +1 -0
- package/corpus/templates/analytics/actions/prometheus.ts +1 -0
- package/corpus/templates/analytics/actions/pylon-issues.ts +1 -0
- package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +1 -0
- package/corpus/templates/analytics/actions/query-dashboard-panel.ts +1 -0
- package/corpus/templates/analytics/actions/query-inbound-forms.ts +1 -0
- package/corpus/templates/analytics/actions/run-monitor-check.ts +1 -0
- package/corpus/templates/analytics/actions/sentry.ts +1 -0
- package/corpus/templates/analytics/actions/seo-blog-pages.ts +1 -0
- package/corpus/templates/analytics/actions/seo-page-keywords.ts +1 -0
- package/corpus/templates/analytics/actions/seo-top-keywords.ts +1 -0
- package/corpus/templates/analytics/actions/slack-messages.ts +1 -0
- package/corpus/templates/analytics/actions/stripe.ts +1 -0
- package/corpus/templates/analytics/actions/test-custom-api-connection.ts +1 -0
- package/corpus/templates/analytics/server/lib/real-data-actions.ts +38 -47
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +40 -34
- package/dist/action.d.ts +13 -0
- package/dist/action.js +3 -0
- package/dist/agent/engine/tool-call-journal-seed.d.ts +27 -10
- package/dist/agent/engine/tool-call-journal-seed.js +46 -32
- package/dist/agent/production-agent.d.ts +33 -0
- package/dist/agent/production-agent.js +172 -57
- package/dist/agent/run-loop-with-resume.d.ts +1 -1
- package/dist/agent/run-loop-with-resume.js +49 -35
- package/dist/client/agent-chat-adapter.js +204 -273
- package/dist/client/sse-event-processor.d.ts +7 -0
- package/dist/client/sse-event-processor.js +21 -1
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/observability/routes.d.ts +5 -5
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/actions/github-repo-files.js +1 -0
- package/dist/provider-api/actions/provider-api.js +1 -0
- package/dist/provider-api/actions/staged-datasets.js +1 -0
- package/dist/provider-api/corpus-jobs.js +1 -0
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/secrets/routes.d.ts +9 -9
- package/dist/server/action-discovery.js +2 -0
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/realtime-token.d.ts +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/package.json +3 -3
|
@@ -24,23 +24,35 @@ import { runAgentLoop, appendAgentLoopContinuation, isResumableEngineError, isTr
|
|
|
24
24
|
import { resolveRunSoftTimeoutMs } from "./run-manager.js";
|
|
25
25
|
import { getCurrentTurnEventsForThread } from "./run-store.js";
|
|
26
26
|
import { classifyToolCallJournal, buildResumeJournalNote, } from "./tool-call-journal.js";
|
|
27
|
-
|
|
27
|
+
/**
|
|
28
|
+
* `persisted: false` means the durable half of the turn could not be read, so
|
|
29
|
+
* `events` holds only what this invocation saw. Callers that decide whether to
|
|
30
|
+
* DISCARD user-visible output must not read that as "nothing else happened".
|
|
31
|
+
*/
|
|
32
|
+
async function readCurrentTurnEventsForResume(threadId, turnId, localEvents = []) {
|
|
28
33
|
let persistedEvents = [];
|
|
34
|
+
let persisted = true;
|
|
29
35
|
try {
|
|
36
|
+
// Without the turnId this can return the PREVIOUS turn's events — see
|
|
37
|
+
// `getCurrentTurnEventsForThread`, whose run row is written without await.
|
|
30
38
|
persistedEvents = threadId
|
|
31
|
-
? await getCurrentTurnEventsForThread(threadId)
|
|
39
|
+
? await getCurrentTurnEventsForThread(threadId, turnId)
|
|
32
40
|
: [];
|
|
33
41
|
}
|
|
34
|
-
catch {
|
|
35
|
-
|
|
42
|
+
catch (err) {
|
|
43
|
+
persisted = false;
|
|
44
|
+
console.warn("[run-loop] current-turn ledger read failed:", err instanceof Error ? err.message : String(err));
|
|
36
45
|
}
|
|
37
46
|
if (localEvents.length === 0)
|
|
38
|
-
return persistedEvents;
|
|
47
|
+
return { events: persistedEvents, persisted };
|
|
39
48
|
const seen = new Set(persistedEvents.map((event) => JSON.stringify(event)));
|
|
40
|
-
return
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
49
|
+
return {
|
|
50
|
+
events: [
|
|
51
|
+
...persistedEvents,
|
|
52
|
+
...localEvents.filter((event) => !seen.has(JSON.stringify(event))),
|
|
53
|
+
],
|
|
54
|
+
persisted,
|
|
55
|
+
};
|
|
44
56
|
}
|
|
45
57
|
function actionPreparationContinuationOptions(events) {
|
|
46
58
|
const actionPreparationTool = lastUnfinishedPreparingActionToolFromEvents(events);
|
|
@@ -86,8 +98,8 @@ function appendToolCallJournalNote(messages, events) {
|
|
|
86
98
|
// up — the model still continues, just without the structured journal.
|
|
87
99
|
}
|
|
88
100
|
}
|
|
89
|
-
async function appendContinuationAndJournal(messages, reason, threadId, localEvents = []) {
|
|
90
|
-
const events = await readCurrentTurnEventsForResume(threadId, localEvents);
|
|
101
|
+
async function appendContinuationAndJournal(messages, reason, threadId, turnId, localEvents = []) {
|
|
102
|
+
const { events } = await readCurrentTurnEventsForResume(threadId, turnId, localEvents);
|
|
91
103
|
appendAgentLoopContinuation(messages, reason, actionPreparationContinuationOptions(events));
|
|
92
104
|
appendToolCallJournalNote(messages, events);
|
|
93
105
|
}
|
|
@@ -95,21 +107,23 @@ async function appendContinuationAndJournal(messages, reason, threadId, localEve
|
|
|
95
107
|
* Rebuild the same safe continuation context for a logical turn that resumes
|
|
96
108
|
* in a fresh hosted invocation.
|
|
97
109
|
*/
|
|
98
|
-
export async function appendDurableContinuationContext(messages, reason, threadId) {
|
|
99
|
-
await appendContinuationAndJournal(messages, reason, threadId);
|
|
110
|
+
export async function appendDurableContinuationContext(messages, reason, threadId, turnId) {
|
|
111
|
+
await appendContinuationAndJournal(messages, reason, threadId, turnId);
|
|
100
112
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
+
/**
|
|
114
|
+
* `"unknown"` is not `"none"`: the only caller uses this to decide whether to
|
|
115
|
+
* emit `clear`, and `clear` WIPES user-visible output. A transient ledger error
|
|
116
|
+
* must not delete the tool cards that are the user's only proof a side effect
|
|
117
|
+
* landed.
|
|
118
|
+
*/
|
|
119
|
+
async function completedSideEffectInCurrentTurn(threadId, turnId, localEvents = []) {
|
|
120
|
+
const { events, persisted } = await readCurrentTurnEventsForResume(threadId, turnId, localEvents);
|
|
121
|
+
const found = events.some((event) => event.type === "tool_done" &&
|
|
122
|
+
event.completedSideEffect === true &&
|
|
123
|
+
event.isError !== true);
|
|
124
|
+
if (found)
|
|
125
|
+
return "some";
|
|
126
|
+
return persisted ? "none" : "unknown";
|
|
113
127
|
}
|
|
114
128
|
function internalContinuationReasonForAttempt(events) {
|
|
115
129
|
const last = events.at(-1);
|
|
@@ -362,15 +376,15 @@ export async function runAgentLoopDirectWithSoftTimeout(opts, softTimeoutMs, tim
|
|
|
362
376
|
if (internalContinuationReason && !upstreamSignal.aborted) {
|
|
363
377
|
lastAttemptWasUnfinishedContinuation = true;
|
|
364
378
|
const continuationEvents = [...localTurnEvents];
|
|
365
|
-
if (
|
|
379
|
+
if ((await completedSideEffectInCurrentTurn(opts.threadId, opts.turnId, continuationEvents)) === "none") {
|
|
366
380
|
opts.send({ type: "clear" });
|
|
367
381
|
}
|
|
368
|
-
await appendContinuationAndJournal(opts.messages, internalContinuationReason, opts.threadId, continuationEvents);
|
|
382
|
+
await appendContinuationAndJournal(opts.messages, internalContinuationReason, opts.threadId, opts.turnId, continuationEvents);
|
|
369
383
|
continue;
|
|
370
384
|
}
|
|
371
385
|
if (softTimedOut && !upstreamSignal.aborted) {
|
|
372
386
|
lastAttemptWasUnfinishedContinuation = true;
|
|
373
|
-
await appendContinuationAndJournal(opts.messages, "run_timeout", opts.threadId, localTurnEvents);
|
|
387
|
+
await appendContinuationAndJournal(opts.messages, "run_timeout", opts.threadId, opts.turnId, localTurnEvents);
|
|
374
388
|
continue;
|
|
375
389
|
}
|
|
376
390
|
reportFinalOutcome(upstreamSignal.aborted
|
|
@@ -383,10 +397,10 @@ export async function runAgentLoopDirectWithSoftTimeout(opts, softTimeoutMs, tim
|
|
|
383
397
|
// Clear partial text the client received before the abort so the
|
|
384
398
|
// resumed model doesn't re-emit it and produce duplicated output.
|
|
385
399
|
lastAttemptWasUnfinishedContinuation = true;
|
|
386
|
-
if (
|
|
400
|
+
if ((await completedSideEffectInCurrentTurn(opts.threadId, opts.turnId, localTurnEvents)) === "none") {
|
|
387
401
|
opts.send({ type: "clear" });
|
|
388
402
|
}
|
|
389
|
-
await appendContinuationAndJournal(opts.messages, "run_timeout", opts.threadId, localTurnEvents);
|
|
403
|
+
await appendContinuationAndJournal(opts.messages, "run_timeout", opts.threadId, opts.turnId, localTurnEvents);
|
|
390
404
|
continue;
|
|
391
405
|
}
|
|
392
406
|
const transientRateLimit = isTransientProviderRateLimitError(err);
|
|
@@ -402,10 +416,10 @@ export async function runAgentLoopDirectWithSoftTimeout(opts, softTimeoutMs, tim
|
|
|
402
416
|
rateLimitRetryFitsBudget) {
|
|
403
417
|
lastAttemptWasUnfinishedContinuation = true;
|
|
404
418
|
backgroundRateLimitContinuations++;
|
|
405
|
-
if (
|
|
419
|
+
if ((await completedSideEffectInCurrentTurn(opts.threadId, opts.turnId, localTurnEvents)) === "none") {
|
|
406
420
|
opts.send({ type: "clear" });
|
|
407
421
|
}
|
|
408
|
-
await appendContinuationAndJournal(opts.messages, "rate_limited", opts.threadId, localTurnEvents);
|
|
422
|
+
await appendContinuationAndJournal(opts.messages, "rate_limited", opts.threadId, opts.turnId, localTurnEvents);
|
|
409
423
|
await waitForBackgroundRateLimitCooldown(upstreamSignal);
|
|
410
424
|
continue;
|
|
411
425
|
}
|
|
@@ -424,10 +438,10 @@ export async function runAgentLoopDirectWithSoftTimeout(opts, softTimeoutMs, tim
|
|
|
424
438
|
// the in-memory messages array, so the next attempt re-emits it).
|
|
425
439
|
if (!upstreamSignal.aborted && isResumableEngineError(err)) {
|
|
426
440
|
lastAttemptWasUnfinishedContinuation = true;
|
|
427
|
-
if (
|
|
441
|
+
if ((await completedSideEffectInCurrentTurn(opts.threadId, opts.turnId, localTurnEvents)) === "none") {
|
|
428
442
|
opts.send({ type: "clear" });
|
|
429
443
|
}
|
|
430
|
-
await appendContinuationAndJournal(opts.messages, continuationReasonForResumableError(err), opts.threadId, localTurnEvents);
|
|
444
|
+
await appendContinuationAndJournal(opts.messages, continuationReasonForResumableError(err), opts.threadId, opts.turnId, localTurnEvents);
|
|
431
445
|
continue;
|
|
432
446
|
}
|
|
433
447
|
if (upstreamSignal.aborted) {
|
|
@@ -467,7 +481,7 @@ export async function runAgentLoopDirectWithSoftTimeout(opts, softTimeoutMs, tim
|
|
|
467
481
|
// the terminal message stands alone instead of trailing a half sentence.
|
|
468
482
|
// Preserve completed tool cards: they are the user's only durable proof
|
|
469
483
|
// that a side effect landed before the final assistant note timed out.
|
|
470
|
-
if (
|
|
484
|
+
if ((await completedSideEffectInCurrentTurn(opts.threadId, opts.turnId, localTurnEvents)) === "none") {
|
|
471
485
|
opts.send({ type: "clear" });
|
|
472
486
|
}
|
|
473
487
|
opts.send({
|