@agent-native/core 0.14.0 → 0.14.2

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.
Files changed (50) hide show
  1. package/dist/agent/engine/builder-engine.d.ts.map +1 -1
  2. package/dist/agent/engine/builder-engine.js +5 -1
  3. package/dist/agent/engine/builder-engine.js.map +1 -1
  4. package/dist/agent/run-loop-with-resume.d.ts +45 -0
  5. package/dist/agent/run-loop-with-resume.d.ts.map +1 -0
  6. package/dist/agent/run-loop-with-resume.js +121 -0
  7. package/dist/agent/run-loop-with-resume.js.map +1 -0
  8. package/dist/agent/run-manager.d.ts.map +1 -1
  9. package/dist/agent/run-manager.js +11 -5
  10. package/dist/agent/run-manager.js.map +1 -1
  11. package/dist/agent/run-store.d.ts +18 -0
  12. package/dist/agent/run-store.d.ts.map +1 -1
  13. package/dist/agent/run-store.js +66 -8
  14. package/dist/agent/run-store.js.map +1 -1
  15. package/dist/client/AgentPanel.d.ts.map +1 -1
  16. package/dist/client/AgentPanel.js +10 -0
  17. package/dist/client/AgentPanel.js.map +1 -1
  18. package/dist/client/AssistantChat.d.ts.map +1 -1
  19. package/dist/client/AssistantChat.js +7 -44
  20. package/dist/client/AssistantChat.js.map +1 -1
  21. package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
  22. package/dist/client/MultiTabAssistantChat.js +19 -10
  23. package/dist/client/MultiTabAssistantChat.js.map +1 -1
  24. package/dist/client/composer/PromptComposer.d.ts.map +1 -1
  25. package/dist/client/composer/PromptComposer.js +28 -3
  26. package/dist/client/composer/PromptComposer.js.map +1 -1
  27. package/dist/client/use-chat-threads.d.ts +0 -6
  28. package/dist/client/use-chat-threads.d.ts.map +1 -1
  29. package/dist/client/use-chat-threads.js +119 -89
  30. package/dist/client/use-chat-threads.js.map +1 -1
  31. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  32. package/dist/server/agent-chat-plugin.js +36 -95
  33. package/dist/server/agent-chat-plugin.js.map +1 -1
  34. package/dist/server/auth.d.ts.map +1 -1
  35. package/dist/server/auth.js +12 -1
  36. package/dist/server/auth.js.map +1 -1
  37. package/dist/server/google-auth-plugin.d.ts.map +1 -1
  38. package/dist/server/google-auth-plugin.js +40 -1
  39. package/dist/server/google-auth-plugin.js.map +1 -1
  40. package/dist/server/google-oauth.d.ts.map +1 -1
  41. package/dist/server/google-oauth.js +8 -7
  42. package/dist/server/google-oauth.js.map +1 -1
  43. package/dist/server/oauth-return-url.d.ts +6 -0
  44. package/dist/server/oauth-return-url.d.ts.map +1 -0
  45. package/dist/server/oauth-return-url.js +78 -0
  46. package/dist/server/oauth-return-url.js.map +1 -0
  47. package/dist/server/onboarding-html.d.ts.map +1 -1
  48. package/dist/server/onboarding-html.js +40 -1
  49. package/dist/server/onboarding-html.js.map +1 -1
  50. package/package.json +1 -1
@@ -1,8 +1,8 @@
1
1
  import { runWithRequestContext, getRequestOrgId, getRequestUserEmail, getRequestRunContext, ensureRequestRunContext, } from "./request-context.js";
2
2
  import { getSetting, putSetting } from "../settings/store.js";
3
3
  import { getH3App, markDefaultPluginProvided, trackPluginInit, } from "./framework-request-handler.js";
4
- import { createProductionAgentHandler, runAgentLoop, actionsToEngineTools, getActiveRunForThreadAsync, abortRun, subscribeToRun, appendAgentLoopContinuation, isResumableEngineError, continuationReasonForResumableError, } from "../agent/production-agent.js";
5
- import { resolveRunSoftTimeoutMs } from "../agent/run-manager.js";
4
+ import { createProductionAgentHandler, actionsToEngineTools, getActiveRunForThreadAsync, abortRun, subscribeToRun, } from "../agent/production-agent.js";
5
+ import { runAgentLoopDirectWithSoftTimeout } from "../agent/run-loop-with-resume.js";
6
6
  import { resolveEngine, createAnthropicEngine, getStoredModelForEngine, } from "../agent/engine/index.js";
7
7
  import { DEFAULT_ANTHROPIC_MODEL } from "../agent/default-model.js";
8
8
  import { attachToolSearch } from "../agent/tool-search.js";
@@ -77,94 +77,6 @@ function resolveArtifactBaseUrl(event) {
77
77
  catch { }
78
78
  return undefined;
79
79
  }
80
- /**
81
- * Cap on continuation iterations inside a single runAgentLoopDirectWithSoftTimeout
82
- * invocation. Each iteration runs a fresh LLM call after the previous one was
83
- * cut off (soft timeout, gateway timeout, network blip). The host's hard
84
- * function timeout (e.g., Lambda's 75s) usually bounds this naturally — but
85
- * a defensive cap prevents an instant-error spiral from looping forever
86
- * inside a hosting environment with a generous budget.
87
- *
88
- * 6 leaves room for: 1 normal completion + a few resume rounds for design
89
- * generation (prompt + 3 variants ≈ 4 LLM calls), with a small safety margin.
90
- */
91
- const MAX_RUN_LOOP_CONTINUATIONS = 6;
92
- async function runAgentLoopDirectWithSoftTimeout(opts, softTimeoutMs) {
93
- const timeoutMs = resolveRunSoftTimeoutMs(softTimeoutMs);
94
- if (timeoutMs <= 0)
95
- return runAgentLoop(opts);
96
- const upstreamSignal = opts.signal;
97
- const usage = {
98
- inputTokens: 0,
99
- outputTokens: 0,
100
- cacheReadTokens: 0,
101
- cacheWriteTokens: 0,
102
- model: opts.model,
103
- };
104
- const addUsage = (next) => {
105
- usage.inputTokens += next.inputTokens;
106
- usage.outputTokens += next.outputTokens;
107
- usage.cacheReadTokens += next.cacheReadTokens;
108
- usage.cacheWriteTokens += next.cacheWriteTokens;
109
- usage.model = next.model;
110
- };
111
- let attempts = 0;
112
- while (!upstreamSignal.aborted && attempts < MAX_RUN_LOOP_CONTINUATIONS) {
113
- attempts++;
114
- const controller = new AbortController();
115
- const abortFromUpstream = () => controller.abort();
116
- if (upstreamSignal.aborted) {
117
- controller.abort();
118
- }
119
- else {
120
- upstreamSignal.addEventListener("abort", abortFromUpstream, {
121
- once: true,
122
- });
123
- }
124
- let softTimedOut = false;
125
- const timer = setTimeout(() => {
126
- if (controller.signal.aborted)
127
- return;
128
- softTimedOut = true;
129
- controller.abort();
130
- }, timeoutMs);
131
- try {
132
- const nextUsage = await runAgentLoop({
133
- ...opts,
134
- signal: controller.signal,
135
- });
136
- addUsage(nextUsage);
137
- if (softTimedOut && !upstreamSignal.aborted) {
138
- appendAgentLoopContinuation(opts.messages, "run_timeout");
139
- continue;
140
- }
141
- return usage;
142
- }
143
- catch (err) {
144
- if (softTimedOut && !upstreamSignal.aborted) {
145
- appendAgentLoopContinuation(opts.messages, "run_timeout");
146
- continue;
147
- }
148
- // Resumable transport / gateway interruptions: the LLM call was cut off
149
- // mid-stream (gateway 45s timeout, socket hang up, function-level
150
- // timeout that didn't trip our soft timer first). Treat it the same
151
- // way as a soft timeout — append a "continue from where you left off"
152
- // nudge and let the loop run another LLM call. The conversation prefix
153
- // up to the cut-off is preserved in opts.messages, and Anthropic's
154
- // prompt cache makes the resume call much faster.
155
- if (!upstreamSignal.aborted && isResumableEngineError(err)) {
156
- appendAgentLoopContinuation(opts.messages, continuationReasonForResumableError(err));
157
- continue;
158
- }
159
- throw err;
160
- }
161
- finally {
162
- clearTimeout(timer);
163
- upstreamSignal.removeEventListener("abort", abortFromUpstream);
164
- }
165
- }
166
- return usage;
167
- }
168
80
  export function assembleA2AFinalResponse(events, toolResults, options = {}) {
169
81
  const responseText = collectFinalResponseTextFromAgentEvents(events);
170
82
  const finalText = appendA2AArtifactLinks(responseText, [...toolResults], {
@@ -4093,11 +4005,40 @@ Non-code requests are still fine on this surface — read data, navigate the UI,
4093
4005
  }
4094
4006
  if (method === "POST") {
4095
4007
  const body = await readBody(event);
4096
- const thread = await createThread(owner, {
4097
- id: body?.id,
4098
- title: body?.title ?? "",
4099
- });
4100
- return thread;
4008
+ // Idempotent: when the caller supplies an id and a thread with
4009
+ // that id already exists for this owner, return it instead of
4010
+ // 500'ing on the UNIQUE constraint. The client can race with
4011
+ // the agent run's `persistSubmittedUserMessage` (which also
4012
+ // creates the thread on first message); we don't want either
4013
+ // racer's POST/onRunPrepared retry to wipe the thread out of
4014
+ // the user's history.
4015
+ if (body?.id) {
4016
+ const existing = await getThread(body.id);
4017
+ if (existing) {
4018
+ if (existing.ownerEmail === owner)
4019
+ return existing;
4020
+ setResponseStatus(event, 409);
4021
+ return { error: "Thread id already in use" };
4022
+ }
4023
+ }
4024
+ try {
4025
+ const thread = await createThread(owner, {
4026
+ id: body?.id,
4027
+ title: body?.title ?? "",
4028
+ });
4029
+ return thread;
4030
+ }
4031
+ catch (err) {
4032
+ // Lost the create race against another in-flight POST or
4033
+ // against `persistSubmittedUserMessage`. Re-fetch and
4034
+ // return the row that actually landed.
4035
+ if (body?.id) {
4036
+ const existing = await getThread(body.id);
4037
+ if (existing && existing.ownerEmail === owner)
4038
+ return existing;
4039
+ }
4040
+ throw err;
4041
+ }
4101
4042
  }
4102
4043
  setResponseStatus(event, 405);
4103
4044
  return { error: "Method not allowed" };