@duetso/agent 0.2.4 → 0.2.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.
Files changed (52) hide show
  1. package/dist/package.json +3 -1
  2. package/dist/src/cli/route.d.ts +4 -8
  3. package/dist/src/cli/route.d.ts.map +1 -1
  4. package/dist/src/cli/route.js +26 -49
  5. package/dist/src/cli/route.js.map +1 -1
  6. package/dist/src/cli.d.ts +2 -0
  7. package/dist/src/cli.d.ts.map +1 -1
  8. package/dist/src/cli.js +12 -2
  9. package/dist/src/cli.js.map +1 -1
  10. package/dist/src/memory/pglite.d.ts +11 -0
  11. package/dist/src/memory/pglite.d.ts.map +1 -1
  12. package/dist/src/memory/pglite.js +77 -4
  13. package/dist/src/memory/pglite.js.map +1 -1
  14. package/dist/src/model-routing/advisor-context.d.ts +71 -0
  15. package/dist/src/model-routing/advisor-context.d.ts.map +1 -0
  16. package/dist/src/model-routing/advisor-context.js +114 -0
  17. package/dist/src/model-routing/advisor-context.js.map +1 -0
  18. package/dist/src/model-routing/advisor-lifecycle.d.ts +27 -0
  19. package/dist/src/model-routing/advisor-lifecycle.d.ts.map +1 -0
  20. package/dist/src/model-routing/advisor-lifecycle.js +61 -0
  21. package/dist/src/model-routing/advisor-lifecycle.js.map +1 -0
  22. package/dist/src/model-routing/advisor.d.ts +11 -6
  23. package/dist/src/model-routing/advisor.d.ts.map +1 -1
  24. package/dist/src/model-routing/advisor.js +16 -4
  25. package/dist/src/model-routing/advisor.js.map +1 -1
  26. package/dist/src/model-routing/prompts.d.ts +4 -0
  27. package/dist/src/model-routing/prompts.d.ts.map +1 -1
  28. package/dist/src/model-routing/prompts.js +36 -11
  29. package/dist/src/model-routing/prompts.js.map +1 -1
  30. package/dist/src/model-routing/router.d.ts +7 -1
  31. package/dist/src/model-routing/router.d.ts.map +1 -1
  32. package/dist/src/model-routing/router.js +10 -2
  33. package/dist/src/model-routing/router.js.map +1 -1
  34. package/dist/src/model-routing/table.d.ts +2 -5
  35. package/dist/src/model-routing/table.d.ts.map +1 -1
  36. package/dist/src/model-routing/table.js +0 -13
  37. package/dist/src/model-routing/table.js.map +1 -1
  38. package/dist/src/session/session.js +1 -1
  39. package/dist/src/turn-runner/prompts.js +1 -1
  40. package/dist/src/turn-runner/tools.d.ts +16 -12
  41. package/dist/src/turn-runner/tools.d.ts.map +1 -1
  42. package/dist/src/turn-runner/tools.js +39 -32
  43. package/dist/src/turn-runner/tools.js.map +1 -1
  44. package/dist/src/turn-runner/turn-runner.d.ts +15 -1
  45. package/dist/src/turn-runner/turn-runner.d.ts.map +1 -1
  46. package/dist/src/turn-runner/turn-runner.js +96 -14
  47. package/dist/src/turn-runner/turn-runner.js.map +1 -1
  48. package/package.json +3 -1
  49. package/dist/src/model-routing/advisor-transcript.d.ts +0 -36
  50. package/dist/src/model-routing/advisor-transcript.d.ts.map +0 -1
  51. package/dist/src/model-routing/advisor-transcript.js +0 -103
  52. package/dist/src/model-routing/advisor-transcript.js.map +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@duetso/agent",
3
- "version": "0.2.4",
3
+ "version": "0.2.5",
4
4
  "description": "An opinionated full-stack agent turn runner with native memories, interrupts, and multi-agent orchestration",
5
5
  "keywords": [
6
6
  "agent",
@@ -49,6 +49,7 @@
49
49
  "lint": "oxlint src/",
50
50
  "prepack": "bun run build",
51
51
  "test": "docker run --rm -v \"$PWD:/src:ro\" -w /work -e HOME=/tmp/home -e DUET_TEST_IN_DOCKER=1 oven/bun:1.3.11 sh -lc 'apt-get update -qq && apt-get install -y -qq git >/dev/null && cp -R /src/. /work && bun install --frozen-lockfile && bun test ./test/*.test.ts'",
52
+ "test:swebench": "bash benchmarks/swebench/test.sh",
52
53
  "example": "bun examples/basic.ts",
53
54
  "example:state-machine": "bun examples/state-machine.ts",
54
55
  "example:tui-playground": "bun examples/tui-playground.ts",
@@ -77,6 +78,7 @@
77
78
  "@types/bun": "^1.3.13",
78
79
  "@types/ms": "^2.1.0",
79
80
  "@types/node": "^22.0.0",
81
+ "e2b": "2.35.0",
80
82
  "husky": "^9.1.7",
81
83
  "oxfmt": "^0.47.0",
82
84
  "oxlint": "^0.16.0",
@@ -1,36 +0,0 @@
1
- import { serializeMessageForObserver } from "../memory/observational.js";
2
- /**
3
- * Text projection produced by {@link serializeMessageForObserver}. The future
4
- * advisor tool can pass that projection directly after serializing the
5
- * `AgentMessage` values in `agent.state.messages`.
6
- */
7
- export type SerializedAdvisorMessage = ReturnType<typeof serializeMessageForObserver>;
8
- /** Inputs needed to assemble advisor context without runtime or persistence dependencies. */
9
- export interface BuildAdvisorTranscriptInput {
10
- /** Serialized first user turn, pinned ahead of every lower-priority section. */
11
- firstUserMessage: SerializedAdvisorMessage;
12
- /** Fully resolved executor prompt; rendered as quoted transcript content, not instructions. */
13
- executorSystemPrompt: string;
14
- /** Chronological `Observation.content` values from `readSessionObservations`. */
15
- observations: readonly string[];
16
- /** Serialized recent messages in oldest-to-newest order. */
17
- tailMessages: readonly SerializedAdvisorMessage[];
18
- /** Maximum estimated tokens allowed in the returned text. */
19
- budgetTokens: number;
20
- }
21
- /** A budgeted advisor payload and the memory system's estimate for that exact text. */
22
- export interface AdvisorTranscript {
23
- /** Curated transcript to send as advisor-call content. */
24
- text: string;
25
- /** Heuristic token estimate for `text`, using the memory system's estimator. */
26
- tokens: number;
27
- /** True when any source content was omitted or shortened to meet the budget. */
28
- truncated: boolean;
29
- }
30
- /**
31
- * Assemble the executor context in descending retention priority. Higher-priority
32
- * prose consumes the budget first; recent messages are retained newest-first at
33
- * whole-message boundaries.
34
- */
35
- export declare function buildAdvisorTranscript(input: BuildAdvisorTranscriptInput): AdvisorTranscript;
36
- //# sourceMappingURL=advisor-transcript.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"advisor-transcript.d.ts","sourceRoot":"","sources":["../../../src/model-routing/advisor-transcript.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,2BAA2B,EAE5B,MAAM,4BAA4B,CAAC;AAEpC;;;;GAIG;AACH,MAAM,MAAM,wBAAwB,GAAG,UAAU,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAEtF,6FAA6F;AAC7F,MAAM,WAAW,2BAA2B;IAC1C,gFAAgF;IAChF,gBAAgB,EAAE,wBAAwB,CAAC;IAC3C,+FAA+F;IAC/F,oBAAoB,EAAE,MAAM,CAAC;IAC7B,iFAAiF;IACjF,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,4DAA4D;IAC5D,YAAY,EAAE,SAAS,wBAAwB,EAAE,CAAC;IAClD,6DAA6D;IAC7D,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,uFAAuF;AACvF,MAAM,WAAW,iBAAiB;IAChC,0DAA0D;IAC1D,IAAI,EAAE,MAAM,CAAC;IACb,gFAAgF;IAChF,MAAM,EAAE,MAAM,CAAC;IACf,gFAAgF;IAChF,SAAS,EAAE,OAAO,CAAC;CACpB;AAOD;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,2BAA2B,GAAG,iBAAiB,CA0C5F"}
@@ -1,103 +0,0 @@
1
- import { estimateTokens, trimMessagesToTranscriptBudget, } from "../memory/observational.js";
2
- const FIRST_USER_HEADING = "## Pinned first user message";
3
- const SYSTEM_PROMPT_HEADING = "## Executor system prompt (quoted content)";
4
- const OBSERVATIONS_HEADING = "## Observations";
5
- const TAIL_HEADING = "## Recent transcript";
6
- /**
7
- * Assemble the executor context in descending retention priority. Higher-priority
8
- * prose consumes the budget first; recent messages are retained newest-first at
9
- * whole-message boundaries.
10
- */
11
- export function buildAdvisorTranscript(input) {
12
- const budgetTokens = normalizeBudget(input.budgetTokens);
13
- let text = "";
14
- let truncated = false;
15
- ({ text, truncated } = appendPriorityContent(text, `${FIRST_USER_HEADING}\n\n${input.firstUserMessage.textPreview}`, budgetTokens, truncated));
16
- const quotedSystemPrompt = quoteAsContent(input.executorSystemPrompt);
17
- ({ text, truncated } = appendPriorityContent(text, `${SYSTEM_PROMPT_HEADING}\n\nThe executor is operating under this system prompt:\n\n${quotedSystemPrompt}`, budgetTokens, truncated));
18
- if (input.observations.length > 0) {
19
- const observations = input.observations
20
- .map((observation, index) => `[Observation ${index + 1}]\n${observation}`)
21
- .join("\n\n");
22
- ({ text, truncated } = appendPriorityContent(text, `${OBSERVATIONS_HEADING}\n\n${observations}`, budgetTokens, truncated));
23
- }
24
- if (estimateTokens(text) < budgetTokens && !truncated) {
25
- const tail = withoutPinnedDuplicate(input.tailMessages, input.firstUserMessage);
26
- const tailResult = buildTailSection(text, tail, budgetTokens);
27
- text = tailResult.text;
28
- truncated = tailResult.truncated;
29
- }
30
- else if (input.tailMessages.length > 0) {
31
- truncated = true;
32
- }
33
- return { text, tokens: estimateTokens(text), truncated };
34
- }
35
- function normalizeBudget(budgetTokens) {
36
- if (!Number.isFinite(budgetTokens))
37
- return 0;
38
- return Math.max(0, Math.floor(budgetTokens));
39
- }
40
- function quoteAsContent(prompt) {
41
- return prompt
42
- .split("\n")
43
- .map((line) => `> ${line}`)
44
- .join("\n");
45
- }
46
- function appendPriorityContent(existing, content, budgetTokens, alreadyTruncated) {
47
- if (alreadyTruncated)
48
- return { text: existing, truncated: true };
49
- const separator = existing.length > 0 ? "\n\n" : "";
50
- const candidate = `${existing}${separator}${content}`;
51
- if (estimateTokens(candidate) <= budgetTokens) {
52
- return { text: candidate, truncated: false };
53
- }
54
- let low = 0;
55
- let high = content.length;
56
- while (low < high) {
57
- const midpoint = Math.ceil((low + high) / 2);
58
- if (estimateTokens(`${existing}${separator}${content.slice(0, midpoint)}`) <= budgetTokens) {
59
- low = midpoint;
60
- }
61
- else {
62
- high = midpoint - 1;
63
- }
64
- }
65
- return { text: `${existing}${separator}${content.slice(0, low)}`, truncated: true };
66
- }
67
- function withoutPinnedDuplicate(tailMessages, firstUserMessage) {
68
- const duplicateIndex = tailMessages.findIndex((message) => message.textPreview === firstUserMessage.textPreview);
69
- return tailMessages.filter((_message, index) => index !== duplicateIndex);
70
- }
71
- function buildTailSection(existing, tailMessages, budgetTokens) {
72
- if (tailMessages.length === 0)
73
- return { text: existing, truncated: false };
74
- const remainingTokens = Math.max(0, budgetTokens - estimateTokens(existing));
75
- const rawMessages = tailMessages.map((message, index) => ({
76
- id: String(index),
77
- createdAt: index,
78
- role: "assistant",
79
- content: [{ type: "text", text: message.textPreview }],
80
- textPreview: message.textPreview,
81
- estimatedTokens: estimateTokens(message.textPreview),
82
- }));
83
- const trimmed = trimMessagesToTranscriptBudget(rawMessages, remainingTokens);
84
- let kept = trimmed.filter((message) => {
85
- const source = rawMessages[Number(message.id)];
86
- return source?.textPreview === message.textPreview;
87
- });
88
- while (true) {
89
- const elidedCount = tailMessages.length - kept.length;
90
- const elision = elidedCount > 0 ? `[earlier transcript elided: ${elidedCount} messages]\n\n` : "";
91
- const body = kept.map((message) => message.textPreview).join("\n\n");
92
- const section = `${TAIL_HEADING}\n\n${elision}${body}`.trimEnd();
93
- const candidate = `${existing}\n\n${section}`;
94
- if (estimateTokens(candidate) <= budgetTokens) {
95
- return { text: candidate, truncated: elidedCount > 0 };
96
- }
97
- if (kept.length === 0) {
98
- return appendPriorityContent(existing, section, budgetTokens, false);
99
- }
100
- kept = kept.slice(1);
101
- }
102
- }
103
- //# sourceMappingURL=advisor-transcript.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"advisor-transcript.js","sourceRoot":"","sources":["../../../src/model-routing/advisor-transcript.ts"],"names":[],"mappings":"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"}