@elevasis/sdk 0.5.15 → 0.5.17

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.
@@ -2551,10 +2551,13 @@ function buildReasoningRequest(iterationContext) {
2551
2551
  systemPrompt,
2552
2552
  tools: toolDefinitions,
2553
2553
  constraints: {
2554
- maxTokens: iterationContext.modelConfig.maxTokens,
2554
+ maxOutputTokens: iterationContext.modelConfig.maxOutputTokens,
2555
2555
  temperature: 1
2556
2556
  },
2557
- memoryContext: iterationContext.memoryManager.toContext(iterationContext.iteration, iterationContext.executionContext.sessionTurnNumber),
2557
+ memoryContext: iterationContext.memoryManager.toContext(
2558
+ iterationContext.iteration,
2559
+ iterationContext.executionContext.sessionTurnNumber
2560
+ ),
2558
2561
  includeMessageAction: isSessionCapable,
2559
2562
  includeNavigateKnowledge: hasKnowledgeMap,
2560
2563
  includeMemoryOps
@@ -2595,7 +2598,7 @@ var GPT5ConfigSchema = z.object({
2595
2598
  apiKey: z.string(),
2596
2599
  temperature: z.literal(1),
2597
2600
  // Required to be exactly 1
2598
- maxTokens: z.number().min(4e3).optional(),
2601
+ maxOutputTokens: z.number().min(4e3).optional(),
2599
2602
  topP: z.number().min(0).max(1).optional(),
2600
2603
  modelOptions: GPT5OptionsSchema.optional()
2601
2604
  });
@@ -2604,7 +2607,7 @@ var MockConfigSchema = z.object({
2604
2607
  provider: z.enum(["mock"]),
2605
2608
  apiKey: z.string(),
2606
2609
  temperature: z.number().min(0).max(2).optional(),
2607
- maxTokens: z.number().min(500).optional(),
2610
+ maxOutputTokens: z.number().min(500).optional(),
2608
2611
  topP: z.number().min(0).max(1).optional(),
2609
2612
  modelOptions: z.object({}).strict().optional()
2610
2613
  // No options supported
@@ -2624,7 +2627,7 @@ var OpenRouterConfigSchema = z.object({
2624
2627
  provider: z.literal("openrouter"),
2625
2628
  apiKey: z.string(),
2626
2629
  temperature: z.number().min(0).max(2).optional(),
2627
- maxTokens: z.number().min(500).optional(),
2630
+ maxOutputTokens: z.number().min(500).optional(),
2628
2631
  topP: z.number().min(0).max(1).optional(),
2629
2632
  modelOptions: OpenRouterOptionsSchema.optional()
2630
2633
  });
@@ -2638,7 +2641,7 @@ var GoogleConfigSchema = z.object({
2638
2641
  apiKey: z.string(),
2639
2642
  temperature: z.literal(1).optional(),
2640
2643
  // Must be 1 for Gemini 3 (changing degrades performance)
2641
- maxTokens: z.number().min(500).optional(),
2644
+ maxOutputTokens: z.number().min(500).optional(),
2642
2645
  topP: z.number().min(0).max(1).optional(),
2643
2646
  modelOptions: GoogleOptionsSchema.optional()
2644
2647
  });
@@ -2648,7 +2651,7 @@ var AnthropicConfigSchema = z.object({
2648
2651
  provider: z.literal("anthropic"),
2649
2652
  apiKey: z.string(),
2650
2653
  temperature: z.number().min(0).max(1).optional(),
2651
- maxTokens: z.number().min(1e3).optional(),
2654
+ maxOutputTokens: z.number().min(1e3).optional(),
2652
2655
  // Anthropic requires max_tokens
2653
2656
  topP: z.number().min(0).max(1).optional(),
2654
2657
  modelOptions: AnthropicOptionsSchema.optional()
@@ -2904,9 +2907,9 @@ var AgentIterationOutputSchema = z.object({
2904
2907
  memoryOps: MemoryOperationsSchema.optional(),
2905
2908
  nextActions: z.array(AgentActionSchema)
2906
2909
  });
2907
- function validateTokenConfiguration(model, maxTokens) {
2910
+ function validateTokenConfiguration(model, maxOutputTokens) {
2908
2911
  const modelInfo = getModelInfo(model);
2909
- const configured = maxTokens || 1e3;
2912
+ const configured = maxOutputTokens || 1e3;
2910
2913
  if (!modelInfo) {
2911
2914
  if (configured < 2e3) {
2912
2915
  throw new InsufficientTokensError(
@@ -2929,15 +2932,20 @@ function validateTokenConfiguration(model, maxTokens) {
2929
2932
  }
2930
2933
  }
2931
2934
  async function callLLMForAgentIteration(adapter, request) {
2932
- validateTokenConfiguration(request.model, request.constraints.maxTokens);
2935
+ validateTokenConfiguration(request.model, request.constraints.maxOutputTokens);
2933
2936
  const messages = [
2934
2937
  { role: "system", content: request.systemPrompt },
2935
2938
  { role: "user", content: request.memoryContext }
2936
2939
  ];
2937
2940
  const response = await adapter.generate({
2938
2941
  messages,
2939
- responseSchema: buildIterationResponseSchema(request.tools, request.includeMessageAction, request.includeNavigateKnowledge, request.includeMemoryOps),
2940
- maxTokens: request.constraints.maxTokens,
2942
+ responseSchema: buildIterationResponseSchema(
2943
+ request.tools,
2944
+ request.includeMessageAction,
2945
+ request.includeNavigateKnowledge,
2946
+ request.includeMemoryOps
2947
+ ),
2948
+ maxOutputTokens: request.constraints.maxOutputTokens,
2941
2949
  temperature: request.constraints.temperature,
2942
2950
  signal: request.signal
2943
2951
  });
@@ -2949,16 +2957,13 @@ async function callLLMForAgentIteration(adapter, request) {
2949
2957
  nextActions: validated.nextActions
2950
2958
  };
2951
2959
  } catch (error) {
2952
- throw new AgentOutputValidationError(
2953
- "Agent iteration output validation failed",
2954
- {
2955
- zodError: error instanceof ZodError ? error.format() : error
2956
- }
2957
- );
2960
+ throw new AgentOutputValidationError("Agent iteration output validation failed", {
2961
+ zodError: error instanceof ZodError ? error.format() : error
2962
+ });
2958
2963
  }
2959
2964
  }
2960
2965
  async function callLLMForAgentCompletion(adapter, request) {
2961
- validateTokenConfiguration(request.model, request.constraints.maxTokens);
2966
+ validateTokenConfiguration(request.model, request.constraints.maxOutputTokens);
2962
2967
  const response = await adapter.generate({
2963
2968
  messages: [
2964
2969
  { role: "system", content: request.systemPrompt },
@@ -2967,7 +2972,7 @@ async function callLLMForAgentCompletion(adapter, request) {
2967
2972
  responseSchema: request.outputSchema,
2968
2973
  // Use output schema directly
2969
2974
  temperature: request.constraints.temperature || 0.3,
2970
- maxTokens: request.constraints.maxTokens,
2975
+ maxOutputTokens: request.constraints.maxOutputTokens,
2971
2976
  signal: request.signal
2972
2977
  });
2973
2978
  return response.output;
@@ -3681,8 +3686,19 @@ function estimateTokens(text) {
3681
3686
  var MAX_SESSION_MEMORY_KEYS = 25;
3682
3687
  var MAX_MEMORY_TOKENS = 32e3;
3683
3688
  var MAX_SINGLE_ENTRY_TOKENS = 2e3;
3689
+ var MAX_TOOL_RESULT_TOKENS = 4e3;
3684
3690
 
3685
3691
  // ../core/src/execution/engine/agent/memory/manager.ts
3692
+ function truncateToolResult(content, maxTokens) {
3693
+ const estimated = estimateTokens(content);
3694
+ if (estimated <= maxTokens) return content;
3695
+ const maxChars = Math.floor(maxTokens * 3.5);
3696
+ const truncated = content.slice(0, maxChars);
3697
+ const omitted = estimated - maxTokens;
3698
+ return truncated + `
3699
+
3700
+ [Response truncated \u2014 estimated ${omitted} tokens omitted. Use more specific filters to get smaller results.]`;
3701
+ }
3686
3702
  var MemoryManager = class {
3687
3703
  constructor(memory, constraints = {}, logger) {
3688
3704
  this.memory = memory;
@@ -3750,17 +3766,31 @@ var MemoryManager = class {
3750
3766
  */
3751
3767
  addToHistory(entry) {
3752
3768
  if (entry.turnNumber === void 0 && entry.type !== "context") {
3753
- throw new AgentMemoryValidationError(
3754
- "turnNumber required for history entries (use null for session memory)",
3755
- {
3756
- entryType: entry.type,
3757
- missingField: "turnNumber",
3758
- iterationNumber: entry.iterationNumber
3759
- }
3760
- );
3769
+ throw new AgentMemoryValidationError("turnNumber required for history entries (use null for session memory)", {
3770
+ entryType: entry.type,
3771
+ missingField: "turnNumber",
3772
+ iterationNumber: entry.iterationNumber
3773
+ });
3774
+ }
3775
+ let content = entry.content;
3776
+ if (entry.type === "tool-result") {
3777
+ const before = content;
3778
+ content = truncateToolResult(content, MAX_TOOL_RESULT_TOKENS);
3779
+ if (content !== before) {
3780
+ const truncateTime = Date.now();
3781
+ this.logger?.action(
3782
+ "memory-tool-result-truncate",
3783
+ `Tool result truncated (${estimateTokens(before)} -> ${MAX_TOOL_RESULT_TOKENS} tokens)`,
3784
+ entry.iterationNumber ?? 0,
3785
+ truncateTime,
3786
+ truncateTime,
3787
+ 0
3788
+ );
3789
+ }
3761
3790
  }
3762
3791
  this.memory.history.push({
3763
3792
  ...entry,
3793
+ content,
3764
3794
  timestamp: Date.now()
3765
3795
  });
3766
3796
  this.autoCompact();
@@ -4416,7 +4446,7 @@ var Agent = class {
4416
4446
  memoryContext: this.memoryManager.toContext(this.iterationNumber, this.executionContext?.sessionTurnNumber),
4417
4447
  outputSchema,
4418
4448
  constraints: {
4419
- maxTokens: this.modelConfig.maxTokens,
4449
+ maxOutputTokens: this.modelConfig.maxOutputTokens,
4420
4450
  temperature
4421
4451
  },
4422
4452
  model: this.modelConfig.model,
@@ -4742,7 +4772,7 @@ var PostMessageLLMAdapter = class {
4742
4772
  messages: request.messages,
4743
4773
  responseSchema: request.responseSchema,
4744
4774
  temperature: request.temperature,
4745
- maxTokens: request.maxTokens
4775
+ maxOutputTokens: request.maxOutputTokens
4746
4776
  }
4747
4777
  });
4748
4778
  return { output: result };
@@ -4908,7 +4938,10 @@ var scheduler = createAdapter("scheduler", [
4908
4938
 
4909
4939
  // src/worker/adapters/llm.ts
4910
4940
  var llm = {
4911
- generate: (params) => platform.call({ tool: "llm", method: "generate", params })
4941
+ generate: async (params) => {
4942
+ const result = await platform.call({ tool: "llm", method: "generate", params });
4943
+ return { output: result };
4944
+ }
4912
4945
  };
4913
4946
 
4914
4947
  // src/worker/adapters/storage.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elevasis/sdk",
3
- "version": "0.5.15",
3
+ "version": "0.5.17",
4
4
  "description": "SDK for building Elevasis organization resources",
5
5
  "type": "module",
6
6
  "bin": {
@@ -73,15 +73,15 @@ The `/docs` command manages the permanent `docs/` tree -- everything except `doc
73
73
 
74
74
  ### `/work` Command
75
75
 
76
- The `/work` command manages in-progress task tracking across sessions. It uses `docs/in-progress/` for task documents with standardized frontmatter (`status: planned | in-progress | complete`). Operations:
76
+ The `/work` command manages in-progress task tracking across sessions. It uses `docs/in-progress/` for task documents with standardized frontmatter (`status: planned | in-progress | complete`).
77
77
 
78
- - **`/work`** (no arguments) -- Numbered list sorted by status (`in-progress` first) with last-saved date and current step. Pick by number to auto-resume.
79
- - **`/work create`** -- Guided interview (5 questions) covering objective, acceptance criteria, relation to existing work, investigation needed, and placement. New docs start with `status: planned`. Placement is determined intelligently: related directory, new directory for multi-file tasks, flat file for small tasks.
80
- - **`/work save`** -- Comprehensive snapshot: progress markers, files modified table, key docs to read on resume, and a copy-pasteable "To continue" prompt. Proactively suggested before context pressure builds.
81
- - **`/work resume [<name>]`** -- Load a task by number, keyword, or auto-detect. Loads key docs in parallel and verifies referenced files exist. No file paths required.
82
- - **`/work complete`** -- Seven-step pipeline: resolve target, validate readiness, clean doc (strip resume context, remove progress markers, target 200-400 lines), determine destination in `docs/`, confirm with user, move, verify.
78
+ `/work` is intent-driven -- the agent detects what to do from context rather than requiring explicit subcommands:
83
79
 
84
- When all plan steps for a task are marked COMPLETE and the user appears to be moving on, the agent proactively suggests running `/work complete`.
80
+ - **`/work`** (no arguments) -- Lists tasks sorted by status (`in-progress` first) with last-saved date and current step. Pick by number or name to auto-resume, or describe new work to auto-create a task.
81
+ - **Auto-create** -- When the user describes work that doesn't match an existing task, the agent creates a task doc automatically. If intent is clear, it skips the interview; if ambiguous, it asks 1-2 focused questions.
82
+ - **Auto-save** -- The agent saves progress silently when the conversation context is getting heavy, the user is wrapping up, or 2+ steps have been completed without saving. Updates progress markers, files modified, and resume context.
83
+ - **Auto-resume** -- When the user picks an existing task (by number, name, or keyword), the agent loads context and resumes automatically.
84
+ - **Suggest complete** -- When all plan steps are marked COMPLETE, the agent suggests finalizing: "All steps for '`{task}`' look done. Want me to finalize it?" It never auto-invokes completion. The complete flow validates readiness, cleans the doc (strips resume context, removes progress markers, targets 200-400 lines), determines destination in `docs/`, confirms with user, moves, and verifies.
85
85
 
86
86
  **Directory conventions for `docs/in-progress/`:**
87
87
 
@@ -21,7 +21,7 @@ Running `elevasis-sdk init my-project` produces the following agent infrastructu
21
21
  │ ├── tutorial.md # Progressive learning path (3 tracks)
22
22
  │ └── work.md # Task tracking
23
23
  ├── hooks/
24
- │ └── enforce-sdk-boundary.mjs # Blocks destructive git, gh CLI, external writes
24
+ │ └── enforce-sdk-boundary.mjs # Blocks file modifications outside project boundary
25
25
  ├── skills/
26
26
  │ └── creds/SKILL.md # Credential management (auto-triggers)
27
27
  └── rules/
@@ -167,15 +167,15 @@ Section templates by doc type:
167
167
 
168
168
  **Command Routing Reference:**
169
169
 
170
- | Scenario | Command |
171
- | --------------------------------------- | -------------- |
172
- | Starting new work | `/work create` |
173
- | Resuming yesterday's work | `/work resume` |
174
- | Browsing what docs exist | `/docs` |
175
- | Creating a reference doc (not a task) | `/docs create` |
176
- | Checking if docs match current code | `/docs verify` |
177
- | Full maintenance pipeline (8 steps) | `/meta fix` |
178
- | Deploying code and auto-generating maps | `/meta deploy` |
170
+ | Scenario | Command |
171
+ | --------------------------------------- | ----------------------------------------------------- |
172
+ | Starting new work | `/work` (auto-detects new work from your description) |
173
+ | Resuming yesterday's work | `/work` (auto-resumes if one task is in-progress) |
174
+ | Browsing what docs exist | `/docs` |
175
+ | Creating a reference doc (not a task) | `/docs create` |
176
+ | Checking if docs match current code | `/docs verify` |
177
+ | Full maintenance pipeline (8 steps) | `/meta fix` |
178
+ | Deploying code and auto-generating maps | `/meta deploy` |
179
179
 
180
180
  ---
181
181
 
@@ -96,7 +96,7 @@ This file is NOT scaffolded by default. The agent creates it the first time you
96
96
 
97
97
  ### `docs/in-progress/`
98
98
 
99
- Work-in-progress task documents created by `/work create`. Each file represents an active work item with objective, plan, progress markers, and resume context. `/work complete` moves finished items to their permanent location in `docs/`.
99
+ Work-in-progress task documents managed by `/work`. Each file represents an active work item with objective, plan, progress markers, and resume context. When all steps are complete, the agent suggests finalizing the task, which moves finished items to their permanent location in `docs/`.
100
100
 
101
101
  This directory is NOT deployed -- it is filtered out during the doc scan in `elevasis-sdk deploy`.
102
102
 
@@ -112,7 +112,7 @@ Only `src/` and `docs/` are scaffolded by `elevasis-sdk init`. The following dir
112
112
  | `src/example/` | `elevasis-sdk init` (default) | Always -- echo starter workflow lives here (replace with your own) |
113
113
  | `src/shared/` | `elevasis-sdk init` (default) | Always -- cross-domain shared utilities (starts empty) |
114
114
  | `docs/` | `elevasis-sdk init` (default) | Always |
115
- | `docs/in-progress/` | Agent (on first `/work create`) | When you create a task doc for in-progress work |
115
+ | `docs/in-progress/` | Agent (on first `/work`) | When you create a task doc for in-progress work |
116
116
  | `docs/project-map.mdx` | `elevasis-sdk deploy` | Auto-generated on every deploy |
117
117
  | `docs/priorities.mdx` | Agent (on first goal discussion) | When you discuss project goals or priorities |
118
118
  | `data/` | Agent (on demand) | When you connect a database |
@@ -224,7 +224,7 @@ The `.claude/commands/` directory contains four commands covering the core devel
224
224
 
225
225
  - **`/meta`** -- Project lifecycle: init, status, fix, deploy, health
226
226
  - **`/docs`** -- Browse, create, and verify permanent documentation
227
- - **`/work`** -- Task tracking across sessions: list, create, save, resume, complete
227
+ - **`/work`** -- Task tracking across sessions: auto-detects intent (create, save, resume); suggests complete
228
228
  - **`/tutorial`** -- Progressive learning path adapted to your skill profile
229
229
 
230
230
  For detailed command documentation, see [Agent System](agent).
@@ -31,7 +31,7 @@ my-project/
31
31
  │ │ ├── tutorial.md # Progressive learning
32
32
  │ │ └── work.md # Task tracking
33
33
  │ ├── hooks/
34
- │ │ └── enforce-sdk-boundary.mjs # Blocks destructive commands (auto-loaded)
34
+ │ │ └── enforce-sdk-boundary.mjs # Blocks file modifications outside project (auto-loaded)
35
35
  │ ├── scripts/
36
36
  │ │ └── statusline-command.js # Dynamic status line script
37
37
  │ ├── skills/