@komputer-ai/sdk 0.11.2 → 0.11.3

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.
@@ -0,0 +1,69 @@
1
+ .gitignore
2
+ README.md
3
+ docs/AgentListResponse.md
4
+ docs/AgentResponse.md
5
+ docs/AgentsApi.md
6
+ docs/ConnectorResponse.md
7
+ docs/ConnectorsApi.md
8
+ docs/CreateAgentRequest.md
9
+ docs/CreateConnectorRequest.md
10
+ docs/CreateMemoryRequest.md
11
+ docs/CreateScheduleAgentSpec.md
12
+ docs/CreateScheduleRequest.md
13
+ docs/CreateSecretRequest.md
14
+ docs/CreateSkillRequest.md
15
+ docs/MemoriesApi.md
16
+ docs/MemoryResponse.md
17
+ docs/OfficeListResponse.md
18
+ docs/OfficeMemberResponse.md
19
+ docs/OfficeResponse.md
20
+ docs/OfficesApi.md
21
+ docs/PatchAgentRequest.md
22
+ docs/PatchMemoryRequest.md
23
+ docs/PatchScheduleRequest.md
24
+ docs/PatchSkillRequest.md
25
+ docs/ScheduleListResponse.md
26
+ docs/ScheduleResponse.md
27
+ docs/SchedulesApi.md
28
+ docs/SecretListResponse.md
29
+ docs/SecretResponse.md
30
+ docs/SecretsApi.md
31
+ docs/SkillResponse.md
32
+ docs/SkillsApi.md
33
+ docs/TemplatesApi.md
34
+ docs/UpdateSecretRequest.md
35
+ src/apis/AgentsApi.ts
36
+ src/apis/ConnectorsApi.ts
37
+ src/apis/MemoriesApi.ts
38
+ src/apis/OfficesApi.ts
39
+ src/apis/SchedulesApi.ts
40
+ src/apis/SecretsApi.ts
41
+ src/apis/SkillsApi.ts
42
+ src/apis/TemplatesApi.ts
43
+ src/apis/index.ts
44
+ src/models/AgentListResponse.ts
45
+ src/models/AgentResponse.ts
46
+ src/models/ConnectorResponse.ts
47
+ src/models/CreateAgentRequest.ts
48
+ src/models/CreateConnectorRequest.ts
49
+ src/models/CreateMemoryRequest.ts
50
+ src/models/CreateScheduleAgentSpec.ts
51
+ src/models/CreateScheduleRequest.ts
52
+ src/models/CreateSecretRequest.ts
53
+ src/models/CreateSkillRequest.ts
54
+ src/models/MemoryResponse.ts
55
+ src/models/OfficeListResponse.ts
56
+ src/models/OfficeMemberResponse.ts
57
+ src/models/OfficeResponse.ts
58
+ src/models/PatchAgentRequest.ts
59
+ src/models/PatchMemoryRequest.ts
60
+ src/models/PatchScheduleRequest.ts
61
+ src/models/PatchSkillRequest.ts
62
+ src/models/ScheduleListResponse.ts
63
+ src/models/ScheduleResponse.ts
64
+ src/models/SecretListResponse.ts
65
+ src/models/SecretResponse.ts
66
+ src/models/SkillResponse.ts
67
+ src/models/UpdateSecretRequest.ts
68
+ src/models/index.ts
69
+ src/runtime.ts
@@ -0,0 +1 @@
1
+ 7.21.0
package/README.md CHANGED
@@ -1,147 +1,172 @@
1
- # komputer-ai TypeScript SDK
1
+ # @komputer-ai/sdk@0.1.0
2
2
 
3
- TypeScript/JavaScript client for the [komputer.ai](https://github.com/kontroloop-ai/komputer-ai) platform.
3
+ A TypeScript SDK client for the localhost API.
4
4
 
5
- ## Installation
6
-
7
- ```bash
8
- npm install @komputer-ai/sdk
9
- ```
5
+ ## Usage
10
6
 
11
- Or install directly from the repository:
7
+ First, install the SDK from npm.
12
8
 
13
9
  ```bash
14
- git clone https://github.com/kontroloop-ai/komputer-ai.git
15
- cd komputer-ai/komputer-sdk/typescript && npm install && npm run build
10
+ npm install @komputer-ai/sdk --save
16
11
  ```
17
12
 
18
- ## Quick Start
13
+ Next, try it out.
19
14
 
20
- ```typescript
21
- import { KomputerClient } from "@komputer-ai/sdk";
22
15
 
23
- const client = new KomputerClient("http://localhost:8080");
16
+ ```ts
17
+ import {
18
+ Configuration,
19
+ AgentsApi,
20
+ } from '@komputer-ai/sdk';
21
+ import type { AgentsNameWsGetRequest } from '@komputer-ai/sdk';
24
22
 
25
- // Create an agent
26
- const agent = await client.createAgent({
27
- name: "my-agent",
28
- instructions: "Summarize the latest Kubernetes release notes",
29
- model: "claude-sonnet-4-6",
30
- });
23
+ async function example() {
24
+ console.log("🚀 Testing @komputer-ai/sdk SDK...");
25
+ const api = new AgentsApi();
31
26
 
32
- // Stream events as the agent works
33
- for await (const event of client.watchAgent("my-agent")) {
34
- if (event.type === "text") {
35
- console.log(event.payload.content);
36
- } else if (event.type === "task_completed") {
37
- console.log(`Done — cost: $${event.payload.cost_usd}`);
38
- break;
27
+ const body = {
28
+ // string | Agent name
29
+ name: name_example,
30
+ } satisfies AgentsNameWsGetRequest;
31
+
32
+ try {
33
+ const data = await api.agentsNameWsGet(body);
34
+ console.log(data);
35
+ } catch (error) {
36
+ console.error(error);
39
37
  }
40
38
  }
41
- ```
42
-
43
- ## Usage
44
39
 
45
- ### Agents
46
-
47
- ```typescript
48
- // Create
49
- await client.createAgent({ name: "researcher", instructions: "Research AI trends", model: "claude-sonnet-4-6" });
50
-
51
- // List
52
- const agents = await client.listAgents();
53
-
54
- // Get
55
- const agent = await client.getAgent("researcher");
56
-
57
- // Update
58
- await client.patchAgent({ name: "researcher", model: "claude-haiku-4-5-20251001", lifecycle: "Sleep" });
59
-
60
- // Cancel a running task
61
- await client.cancelAgentTask("researcher");
62
-
63
- // Delete
64
- await client.deleteAgent("researcher");
40
+ // Run the test
41
+ example().catch(console.error);
65
42
  ```
66
43
 
67
- ### Memories
68
44
 
69
- ```typescript
70
- await client.createMemory({ name: "company-context", content: "We are a B2B SaaS company.", description: "Background" });
71
- await client.patchAgent({ name: "my-agent", memories: ["company-context"] });
72
-
73
- const memories = await client.listMemories();
74
- await client.patchMemory({ name: "company-context", content: "Updated context." });
75
- await client.deleteMemory("company-context");
76
- ```
45
+ ## Documentation
46
+
47
+ ### API Endpoints
48
+
49
+ All URIs are relative to *http://localhost:8080/api/v1*
50
+
51
+ | Class | Method | HTTP request | Description
52
+ | ----- | ------ | ------------ | -------------
53
+ *AgentsApi* | [**agentsNameWsGet**](docs/AgentsApi.md#agentsnamewsget) | **GET** /agents/{name}/ws | Stream agent events (WebSocket)
54
+ *AgentsApi* | [**cancelAgentTask**](docs/AgentsApi.md#cancelagenttask) | **POST** /agents/{name}/cancel | Cancel agent task
55
+ *AgentsApi* | [**createAgent**](docs/AgentsApi.md#createagentoperation) | **POST** /agents | Create agent or send task
56
+ *AgentsApi* | [**deleteAgent**](docs/AgentsApi.md#deleteagent) | **DELETE** /agents/{name} | Delete agent
57
+ *AgentsApi* | [**getAgent**](docs/AgentsApi.md#getagent) | **GET** /agents/{name} | Get agent details
58
+ *AgentsApi* | [**getAgentEvents**](docs/AgentsApi.md#getagentevents) | **GET** /agents/{name}/events | Get agent events
59
+ *AgentsApi* | [**listAgents**](docs/AgentsApi.md#listagents) | **GET** /agents | List agents
60
+ *AgentsApi* | [**patchAgent**](docs/AgentsApi.md#patchagentoperation) | **PATCH** /agents/{name} | Patch agent
61
+ *ConnectorsApi* | [**createConnector**](docs/ConnectorsApi.md#createconnectoroperation) | **POST** /connectors | Create connector
62
+ *ConnectorsApi* | [**deleteConnector**](docs/ConnectorsApi.md#deleteconnector) | **DELETE** /connectors/{name} | Delete connector
63
+ *ConnectorsApi* | [**getConnector**](docs/ConnectorsApi.md#getconnector) | **GET** /connectors/{name} | Get connector details
64
+ *ConnectorsApi* | [**listConnectorTools**](docs/ConnectorsApi.md#listconnectortools) | **GET** /connectors/{name}/tools | List connector tools
65
+ *ConnectorsApi* | [**listConnectors**](docs/ConnectorsApi.md#listconnectors) | **GET** /connectors | List connectors
66
+ *MemoriesApi* | [**createMemory**](docs/MemoriesApi.md#creatememoryoperation) | **POST** /memories | Create memory
67
+ *MemoriesApi* | [**deleteMemory**](docs/MemoriesApi.md#deletememory) | **DELETE** /memories/{name} | Delete memory
68
+ *MemoriesApi* | [**getMemory**](docs/MemoriesApi.md#getmemory) | **GET** /memories/{name} | Get memory details
69
+ *MemoriesApi* | [**listMemories**](docs/MemoriesApi.md#listmemories) | **GET** /memories | List memories
70
+ *MemoriesApi* | [**patchMemory**](docs/MemoriesApi.md#patchmemoryoperation) | **PATCH** /memories/{name} | Patch memory
71
+ *OfficesApi* | [**deleteOffice**](docs/OfficesApi.md#deleteoffice) | **DELETE** /offices/{name} | Delete office
72
+ *OfficesApi* | [**getOffice**](docs/OfficesApi.md#getoffice) | **GET** /offices/{name} | Get office details
73
+ *OfficesApi* | [**getOfficeEvents**](docs/OfficesApi.md#getofficeevents) | **GET** /offices/{name}/events | Get office events
74
+ *OfficesApi* | [**listOffices**](docs/OfficesApi.md#listoffices) | **GET** /offices | List offices
75
+ *SchedulesApi* | [**createSchedule**](docs/SchedulesApi.md#createscheduleoperation) | **POST** /schedules | Create schedule
76
+ *SchedulesApi* | [**deleteSchedule**](docs/SchedulesApi.md#deleteschedule) | **DELETE** /schedules/{name} | Delete schedule
77
+ *SchedulesApi* | [**getSchedule**](docs/SchedulesApi.md#getschedule) | **GET** /schedules/{name} | Get schedule details
78
+ *SchedulesApi* | [**listSchedules**](docs/SchedulesApi.md#listschedules) | **GET** /schedules | List schedules
79
+ *SchedulesApi* | [**patchSchedule**](docs/SchedulesApi.md#patchscheduleoperation) | **PATCH** /schedules/{name} | Patch schedule
80
+ *SecretsApi* | [**createSecret**](docs/SecretsApi.md#createsecretoperation) | **POST** /secrets | Create managed secret
81
+ *SecretsApi* | [**deleteSecret**](docs/SecretsApi.md#deletesecret) | **DELETE** /secrets/{name} | Delete managed secret
82
+ *SecretsApi* | [**listSecrets**](docs/SecretsApi.md#listsecrets) | **GET** /secrets | List secrets
83
+ *SecretsApi* | [**updateSecret**](docs/SecretsApi.md#updatesecretoperation) | **PATCH** /secrets/{name} | Update managed secret
84
+ *SkillsApi* | [**createSkill**](docs/SkillsApi.md#createskilloperation) | **POST** /skills | Create skill
85
+ *SkillsApi* | [**deleteSkill**](docs/SkillsApi.md#deleteskill) | **DELETE** /skills/{name} | Delete skill
86
+ *SkillsApi* | [**getSkill**](docs/SkillsApi.md#getskill) | **GET** /skills/{name} | Get skill details
87
+ *SkillsApi* | [**listSkills**](docs/SkillsApi.md#listskills) | **GET** /skills | List skills
88
+ *SkillsApi* | [**patchSkill**](docs/SkillsApi.md#patchskilloperation) | **PATCH** /skills/{name} | Patch skill
89
+ *TemplatesApi* | [**listTemplates**](docs/TemplatesApi.md#listtemplates) | **GET** /templates | List agent templates
90
+ *TemplatesApi* | [**namespacesGet**](docs/TemplatesApi.md#namespacesget) | **GET** /namespaces | List namespaces
91
+
92
+
93
+ ### Models
94
+
95
+ - [AgentListResponse](docs/AgentListResponse.md)
96
+ - [AgentResponse](docs/AgentResponse.md)
97
+ - [ConnectorResponse](docs/ConnectorResponse.md)
98
+ - [CreateAgentRequest](docs/CreateAgentRequest.md)
99
+ - [CreateConnectorRequest](docs/CreateConnectorRequest.md)
100
+ - [CreateMemoryRequest](docs/CreateMemoryRequest.md)
101
+ - [CreateScheduleAgentSpec](docs/CreateScheduleAgentSpec.md)
102
+ - [CreateScheduleRequest](docs/CreateScheduleRequest.md)
103
+ - [CreateSecretRequest](docs/CreateSecretRequest.md)
104
+ - [CreateSkillRequest](docs/CreateSkillRequest.md)
105
+ - [MemoryResponse](docs/MemoryResponse.md)
106
+ - [OfficeListResponse](docs/OfficeListResponse.md)
107
+ - [OfficeMemberResponse](docs/OfficeMemberResponse.md)
108
+ - [OfficeResponse](docs/OfficeResponse.md)
109
+ - [PatchAgentRequest](docs/PatchAgentRequest.md)
110
+ - [PatchMemoryRequest](docs/PatchMemoryRequest.md)
111
+ - [PatchScheduleRequest](docs/PatchScheduleRequest.md)
112
+ - [PatchSkillRequest](docs/PatchSkillRequest.md)
113
+ - [ScheduleListResponse](docs/ScheduleListResponse.md)
114
+ - [ScheduleResponse](docs/ScheduleResponse.md)
115
+ - [SecretListResponse](docs/SecretListResponse.md)
116
+ - [SecretResponse](docs/SecretResponse.md)
117
+ - [SkillResponse](docs/SkillResponse.md)
118
+ - [UpdateSecretRequest](docs/UpdateSecretRequest.md)
119
+
120
+ ### Authorization
121
+
122
+ Endpoints do not require authorization.
123
+
124
+
125
+ ## About
126
+
127
+ This TypeScript SDK client supports the [Fetch API](https://fetch.spec.whatwg.org/)
128
+ and is automatically generated by the
129
+ [OpenAPI Generator](https://openapi-generator.tech) project:
130
+
131
+ - API version: `1.0`
132
+ - Package version: `0.1.0`
133
+ - Generator version: `7.21.0`
134
+ - Build package: `org.openapitools.codegen.languages.TypeScriptFetchClientCodegen`
135
+
136
+ The generated npm module supports the following:
137
+
138
+ - Environments
139
+ * Node.js
140
+ * Webpack
141
+ * Browserify
142
+ - Language levels
143
+ * ES5 - you must have a Promises/A+ library installed
144
+ * ES6
145
+ - Module systems
146
+ * CommonJS
147
+ * ES6 module system
148
+
149
+
150
+ ## Development
151
+
152
+ ### Building
153
+
154
+ To build the TypeScript source code, you need to have Node.js and npm installed.
155
+ After cloning the repository, navigate to the project directory and run:
77
156
 
78
- ### Skills
79
-
80
- ```typescript
81
- await client.createSkill({ name: "healthcheck", description: "Check service health", content: "curl -s http://api/healthz" });
82
- await client.patchAgent({ name: "my-agent", skills: ["healthcheck"] });
83
-
84
- const skills = await client.listSkills();
85
- await client.deleteSkill("healthcheck");
86
- ```
87
-
88
- ### Schedules
89
-
90
- ```typescript
91
- await client.createSchedule({
92
- name: "daily-report",
93
- schedule: "0 9 * * *",
94
- instructions: "Generate a daily status report",
95
- timezone: "America/New_York",
96
- });
97
-
98
- const schedules = await client.listSchedules();
99
- await client.patchSchedule({ name: "daily-report", schedule: "0 10 * * *" });
100
- await client.deleteSchedule("daily-report");
101
- ```
102
-
103
- ### Secrets
104
-
105
- ```typescript
106
- await client.createSecret({ name: "api-keys", data: { GITHUB_TOKEN: "ghp_xxx", SLACK_TOKEN: "xoxb-xxx" } });
107
- await client.patchAgent({ name: "my-agent", secretRefs: ["api-keys"] });
108
-
109
- const secrets = await client.listSecrets();
110
- await client.deleteSecret("api-keys");
157
+ ```bash
158
+ npm install
159
+ npm run build
111
160
  ```
112
161
 
113
- ### Connectors
162
+ ### Publishing
114
163
 
115
- ```typescript
116
- await client.createConnector({ name: "slack", service: "slack", url: "https://mcp.slack.com", authType: "token" });
117
- await client.patchAgent({ name: "my-agent", connectors: ["slack"] });
164
+ Once you've built the package, you can publish it to npm:
118
165
 
119
- const connectors = await client.listConnectors();
120
- await client.deleteConnector("slack");
166
+ ```bash
167
+ npm publish
121
168
  ```
122
169
 
123
- ### Streaming Events
124
-
125
- ```typescript
126
- for await (const event of client.watchAgent("my-agent")) {
127
- switch (event.type) {
128
- case "task_started":
129
- console.log("Agent started working...");
130
- break;
131
- case "text":
132
- console.log(event.payload.content);
133
- break;
134
- case "tool_use":
135
- console.log(`Using tool: ${event.payload.name}`);
136
- break;
137
- case "task_completed":
138
- console.log(`Done — cost: $${event.payload.cost_usd}`);
139
- break;
140
- case "error":
141
- console.error(event.payload.error);
142
- break;
143
- }
144
- }
145
- ```
170
+ ## License
146
171
 
147
- Event types: `task_started`, `thinking`, `tool_use`, `tool_result`, `text`, `task_completed`, `task_cancelled`, `error`.
172
+ []()
package/dist/client.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * High-level convenience client for the komputer.ai API.
3
3
  *
4
- * Auto-generated by generate_client.py — do not edit manually.
4
+ * Hand-maintained — do not overwrite with generated output.
5
5
  *
6
6
  * @example
7
7
  * const client = new KomputerClient("http://localhost:8080");
@@ -124,7 +124,9 @@ export declare class KomputerClient {
124
124
  name: string;
125
125
  data: Record<string, string>;
126
126
  namespace?: string;
127
- }): Promise<import("./models").SecretResponse>;
127
+ }): Promise<import("./models").SecretResponse | {
128
+ [key: string]: string;
129
+ }>;
128
130
  updateSecret(params: {
129
131
  name: string;
130
132
  data: Record<string, string>;
@@ -169,5 +171,5 @@ export declare class KomputerClient {
169
171
  listTemplates(): Promise<{
170
172
  [key: string]: any;
171
173
  }>;
172
- watchAgent(name: string): AgentEventStream;
174
+ watchAgent(name: string): Promise<AgentEventStream>;
173
175
  }
package/dist/client.js CHANGED
@@ -2,7 +2,7 @@
2
2
  /**
3
3
  * High-level convenience client for the komputer.ai API.
4
4
  *
5
- * Auto-generated by generate_client.py — do not edit manually.
5
+ * Hand-maintained — do not overwrite with generated output.
6
6
  *
7
7
  * @example
8
8
  * const client = new KomputerClient("http://localhost:8080");
@@ -47,7 +47,15 @@ class KomputerClient {
47
47
  }
48
48
  createAgent(params) {
49
49
  return __awaiter(this, void 0, void 0, function* () {
50
- return this._agents.createAgent({ request: { connectors: params.connectors, instructions: params.instructions, lifecycle: params.lifecycle, memories: params.memories, model: params.model, name: params.name, namespace: params.namespace, officeManager: params.officeManager, role: params.role, secretRefs: params.secretRefs, skills: params.skills, systemPrompt: params.systemPrompt, templateRef: params.templateRef } });
50
+ try {
51
+ return yield this._agents.createAgent({ request: { connectors: params.connectors, instructions: params.instructions, lifecycle: params.lifecycle, memories: params.memories, model: params.model, name: params.name, namespace: params.namespace, officeManager: params.officeManager, role: params.role, secretRefs: params.secretRefs, skills: params.skills, systemPrompt: params.systemPrompt, templateRef: params.templateRef } });
52
+ }
53
+ catch (e) {
54
+ if (e instanceof runtime_1.ResponseError && e.response.status === 409) {
55
+ return this._agents.patchAgent({ name: params.name, request: { connectors: params.connectors, instructions: params.instructions, lifecycle: params.lifecycle, memories: params.memories, model: params.model, secretRefs: params.secretRefs, skills: params.skills, systemPrompt: params.systemPrompt, templateRef: params.templateRef } });
56
+ }
57
+ throw e;
58
+ }
51
59
  });
52
60
  }
53
61
  getAgent(name) {
@@ -83,7 +91,15 @@ class KomputerClient {
83
91
  }
84
92
  createMemory(params) {
85
93
  return __awaiter(this, void 0, void 0, function* () {
86
- return this._memories.createMemory({ request: { content: params.content, description: params.description, name: params.name, namespace: params.namespace } });
94
+ try {
95
+ return yield this._memories.createMemory({ request: { content: params.content, description: params.description, name: params.name, namespace: params.namespace } });
96
+ }
97
+ catch (e) {
98
+ if (e instanceof runtime_1.ResponseError && e.response.status === 409) {
99
+ return this._memories.patchMemory({ name: params.name, request: { content: params.content, description: params.description } });
100
+ }
101
+ throw e;
102
+ }
87
103
  });
88
104
  }
89
105
  getMemory(name) {
@@ -109,7 +125,15 @@ class KomputerClient {
109
125
  }
110
126
  createSkill(params) {
111
127
  return __awaiter(this, void 0, void 0, function* () {
112
- return this._skills.createSkill({ request: { content: params.content, description: params.description, name: params.name, namespace: params.namespace } });
128
+ try {
129
+ return yield this._skills.createSkill({ request: { content: params.content, description: params.description, name: params.name, namespace: params.namespace } });
130
+ }
131
+ catch (e) {
132
+ if (e instanceof runtime_1.ResponseError && e.response.status === 409) {
133
+ return this._skills.patchSkill({ name: params.name, request: { content: params.content, description: params.description } });
134
+ }
135
+ throw e;
136
+ }
113
137
  });
114
138
  }
115
139
  getSkill(name) {
@@ -135,7 +159,15 @@ class KomputerClient {
135
159
  }
136
160
  createSchedule(params) {
137
161
  return __awaiter(this, void 0, void 0, function* () {
138
- return this._schedules.createSchedule({ request: { agent: params.agent, agentName: params.agentName, autoDelete: params.autoDelete, instructions: params.instructions, keepAgents: params.keepAgents, name: params.name, namespace: params.namespace, schedule: params.schedule, timezone: params.timezone } });
162
+ try {
163
+ return yield this._schedules.createSchedule({ request: { agent: params.agent, agentName: params.agentName, autoDelete: params.autoDelete, instructions: params.instructions, keepAgents: params.keepAgents, name: params.name, namespace: params.namespace, schedule: params.schedule, timezone: params.timezone } });
164
+ }
165
+ catch (e) {
166
+ if (e instanceof runtime_1.ResponseError && e.response.status === 409) {
167
+ return this._schedules.patchSchedule({ name: params.name, request: { schedule: params.schedule } });
168
+ }
169
+ throw e;
170
+ }
139
171
  });
140
172
  }
141
173
  getSchedule(name) {
@@ -161,7 +193,15 @@ class KomputerClient {
161
193
  }
162
194
  createSecret(params) {
163
195
  return __awaiter(this, void 0, void 0, function* () {
164
- return this._secrets.createSecret({ request: { data: params.data, name: params.name, namespace: params.namespace } });
196
+ try {
197
+ return yield this._secrets.createSecret({ request: { data: params.data, name: params.name, namespace: params.namespace } });
198
+ }
199
+ catch (e) {
200
+ if (e instanceof runtime_1.ResponseError && e.response.status === 409) {
201
+ return this._secrets.updateSecret({ name: params.name, request: { data: params.data, namespace: params.namespace } });
202
+ }
203
+ throw e;
204
+ }
165
205
  });
166
206
  }
167
207
  updateSecret(params) {
@@ -229,8 +269,25 @@ class KomputerClient {
229
269
  }
230
270
  // --- WebSocket ---
231
271
  watchAgent(name) {
232
- const wsUrl = this._baseUrl.replace("http://", "ws://").replace("https://", "wss://");
233
- return new watch_1.AgentEventStream(wsUrl, name);
272
+ return __awaiter(this, void 0, void 0, function* () {
273
+ const wsUrl = this._baseUrl.replace("http://", "ws://").replace("https://", "wss://");
274
+ let history = [];
275
+ try {
276
+ const resp = yield this._agents.getAgentEvents({ name, limit: 200 });
277
+ if (resp && Array.isArray(resp.events)) {
278
+ history = resp.events.map((e) => ({
279
+ agentName: e.agentName || name,
280
+ type: e.type || "",
281
+ timestamp: e.timestamp || "",
282
+ payload: e.payload || {},
283
+ }));
284
+ }
285
+ }
286
+ catch (_a) {
287
+ // History fetch failed — proceed with live-only.
288
+ }
289
+ return new watch_1.AgentEventStream(wsUrl, name, history);
290
+ });
234
291
  }
235
292
  }
236
293
  exports.KomputerClient = KomputerClient;
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * High-level convenience client for the komputer.ai API.
3
3
  *
4
- * Auto-generated by generate_client.py — do not edit manually.
4
+ * Hand-maintained — do not overwrite with generated output.
5
5
  *
6
6
  * @example
7
7
  * const client = new KomputerClient("http://localhost:8080");
@@ -124,7 +124,9 @@ export declare class KomputerClient {
124
124
  name: string;
125
125
  data: Record<string, string>;
126
126
  namespace?: string;
127
- }): Promise<import("./models").SecretResponse>;
127
+ }): Promise<import("./models").SecretResponse | {
128
+ [key: string]: string;
129
+ }>;
128
130
  updateSecret(params: {
129
131
  name: string;
130
132
  data: Record<string, string>;
@@ -169,5 +171,5 @@ export declare class KomputerClient {
169
171
  listTemplates(): Promise<{
170
172
  [key: string]: any;
171
173
  }>;
172
- watchAgent(name: string): AgentEventStream;
174
+ watchAgent(name: string): Promise<AgentEventStream>;
173
175
  }
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * High-level convenience client for the komputer.ai API.
3
3
  *
4
- * Auto-generated by generate_client.py — do not edit manually.
4
+ * Hand-maintained — do not overwrite with generated output.
5
5
  *
6
6
  * @example
7
7
  * const client = new KomputerClient("http://localhost:8080");
@@ -20,7 +20,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
20
20
  step((generator = generator.apply(thisArg, _arguments || [])).next());
21
21
  });
22
22
  };
23
- import { Configuration } from "./runtime";
23
+ import { Configuration, ResponseError } from "./runtime";
24
24
  import { AgentsApi, ConnectorsApi, MemoriesApi, OfficesApi, SchedulesApi, SecretsApi, SkillsApi, TemplatesApi } from "./apis";
25
25
  import { AgentEventStream } from "./watch";
26
26
  export class KomputerClient {
@@ -44,7 +44,15 @@ export class KomputerClient {
44
44
  }
45
45
  createAgent(params) {
46
46
  return __awaiter(this, void 0, void 0, function* () {
47
- return this._agents.createAgent({ request: { connectors: params.connectors, instructions: params.instructions, lifecycle: params.lifecycle, memories: params.memories, model: params.model, name: params.name, namespace: params.namespace, officeManager: params.officeManager, role: params.role, secretRefs: params.secretRefs, skills: params.skills, systemPrompt: params.systemPrompt, templateRef: params.templateRef } });
47
+ try {
48
+ return yield this._agents.createAgent({ request: { connectors: params.connectors, instructions: params.instructions, lifecycle: params.lifecycle, memories: params.memories, model: params.model, name: params.name, namespace: params.namespace, officeManager: params.officeManager, role: params.role, secretRefs: params.secretRefs, skills: params.skills, systemPrompt: params.systemPrompt, templateRef: params.templateRef } });
49
+ }
50
+ catch (e) {
51
+ if (e instanceof ResponseError && e.response.status === 409) {
52
+ return this._agents.patchAgent({ name: params.name, request: { connectors: params.connectors, instructions: params.instructions, lifecycle: params.lifecycle, memories: params.memories, model: params.model, secretRefs: params.secretRefs, skills: params.skills, systemPrompt: params.systemPrompt, templateRef: params.templateRef } });
53
+ }
54
+ throw e;
55
+ }
48
56
  });
49
57
  }
50
58
  getAgent(name) {
@@ -80,7 +88,15 @@ export class KomputerClient {
80
88
  }
81
89
  createMemory(params) {
82
90
  return __awaiter(this, void 0, void 0, function* () {
83
- return this._memories.createMemory({ request: { content: params.content, description: params.description, name: params.name, namespace: params.namespace } });
91
+ try {
92
+ return yield this._memories.createMemory({ request: { content: params.content, description: params.description, name: params.name, namespace: params.namespace } });
93
+ }
94
+ catch (e) {
95
+ if (e instanceof ResponseError && e.response.status === 409) {
96
+ return this._memories.patchMemory({ name: params.name, request: { content: params.content, description: params.description } });
97
+ }
98
+ throw e;
99
+ }
84
100
  });
85
101
  }
86
102
  getMemory(name) {
@@ -106,7 +122,15 @@ export class KomputerClient {
106
122
  }
107
123
  createSkill(params) {
108
124
  return __awaiter(this, void 0, void 0, function* () {
109
- return this._skills.createSkill({ request: { content: params.content, description: params.description, name: params.name, namespace: params.namespace } });
125
+ try {
126
+ return yield this._skills.createSkill({ request: { content: params.content, description: params.description, name: params.name, namespace: params.namespace } });
127
+ }
128
+ catch (e) {
129
+ if (e instanceof ResponseError && e.response.status === 409) {
130
+ return this._skills.patchSkill({ name: params.name, request: { content: params.content, description: params.description } });
131
+ }
132
+ throw e;
133
+ }
110
134
  });
111
135
  }
112
136
  getSkill(name) {
@@ -132,7 +156,15 @@ export class KomputerClient {
132
156
  }
133
157
  createSchedule(params) {
134
158
  return __awaiter(this, void 0, void 0, function* () {
135
- return this._schedules.createSchedule({ request: { agent: params.agent, agentName: params.agentName, autoDelete: params.autoDelete, instructions: params.instructions, keepAgents: params.keepAgents, name: params.name, namespace: params.namespace, schedule: params.schedule, timezone: params.timezone } });
159
+ try {
160
+ return yield this._schedules.createSchedule({ request: { agent: params.agent, agentName: params.agentName, autoDelete: params.autoDelete, instructions: params.instructions, keepAgents: params.keepAgents, name: params.name, namespace: params.namespace, schedule: params.schedule, timezone: params.timezone } });
161
+ }
162
+ catch (e) {
163
+ if (e instanceof ResponseError && e.response.status === 409) {
164
+ return this._schedules.patchSchedule({ name: params.name, request: { schedule: params.schedule } });
165
+ }
166
+ throw e;
167
+ }
136
168
  });
137
169
  }
138
170
  getSchedule(name) {
@@ -158,7 +190,15 @@ export class KomputerClient {
158
190
  }
159
191
  createSecret(params) {
160
192
  return __awaiter(this, void 0, void 0, function* () {
161
- return this._secrets.createSecret({ request: { data: params.data, name: params.name, namespace: params.namespace } });
193
+ try {
194
+ return yield this._secrets.createSecret({ request: { data: params.data, name: params.name, namespace: params.namespace } });
195
+ }
196
+ catch (e) {
197
+ if (e instanceof ResponseError && e.response.status === 409) {
198
+ return this._secrets.updateSecret({ name: params.name, request: { data: params.data, namespace: params.namespace } });
199
+ }
200
+ throw e;
201
+ }
162
202
  });
163
203
  }
164
204
  updateSecret(params) {
@@ -226,7 +266,24 @@ export class KomputerClient {
226
266
  }
227
267
  // --- WebSocket ---
228
268
  watchAgent(name) {
229
- const wsUrl = this._baseUrl.replace("http://", "ws://").replace("https://", "wss://");
230
- return new AgentEventStream(wsUrl, name);
269
+ return __awaiter(this, void 0, void 0, function* () {
270
+ const wsUrl = this._baseUrl.replace("http://", "ws://").replace("https://", "wss://");
271
+ let history = [];
272
+ try {
273
+ const resp = yield this._agents.getAgentEvents({ name, limit: 200 });
274
+ if (resp && Array.isArray(resp.events)) {
275
+ history = resp.events.map((e) => ({
276
+ agentName: e.agentName || name,
277
+ type: e.type || "",
278
+ timestamp: e.timestamp || "",
279
+ payload: e.payload || {},
280
+ }));
281
+ }
282
+ }
283
+ catch (_a) {
284
+ // History fetch failed — proceed with live-only.
285
+ }
286
+ return new AgentEventStream(wsUrl, name, history);
287
+ });
231
288
  }
232
289
  }
@@ -9,6 +9,8 @@ export interface AgentEvent {
9
9
  }
10
10
  /**
11
11
  * Async iterable stream of agent events over WebSocket.
12
+ * Yields pre-fetched history events first, then live WebSocket events,
13
+ * deduplicating by timestamp+type.
12
14
  *
13
15
  * @example
14
16
  * for await (const event of client.watchAgent("my-agent")) {
@@ -22,7 +24,9 @@ export declare class AgentEventStream implements AsyncIterable<AgentEvent> {
22
24
  private queue;
23
25
  private resolve;
24
26
  private done;
25
- constructor(wsUrl: string, agentName: string);
27
+ private seen;
28
+ constructor(wsUrl: string, agentName: string, historyEvents?: AgentEvent[]);
29
+ private dedupKey;
26
30
  [Symbol.asyncIterator](): AsyncIterator<AgentEvent>;
27
31
  close(): void;
28
32
  }
package/dist/esm/watch.js CHANGED
@@ -3,6 +3,8 @@
3
3
  */
4
4
  /**
5
5
  * Async iterable stream of agent events over WebSocket.
6
+ * Yields pre-fetched history events first, then live WebSocket events,
7
+ * deduplicating by timestamp+type.
6
8
  *
7
9
  * @example
8
10
  * for await (const event of client.watchAgent("my-agent")) {
@@ -11,11 +13,20 @@
11
13
  * }
12
14
  */
13
15
  export class AgentEventStream {
14
- constructor(wsUrl, agentName) {
16
+ constructor(wsUrl, agentName, historyEvents) {
15
17
  this.queue = [];
16
18
  this.resolve = null;
17
19
  this.done = false;
20
+ this.seen = new Set();
18
21
  this.agentName = agentName;
22
+ // Seed dedup set and queue with history events.
23
+ if (historyEvents) {
24
+ for (const e of historyEvents) {
25
+ const key = this.dedupKey(e);
26
+ this.seen.add(key);
27
+ this.queue.push(e);
28
+ }
29
+ }
19
30
  this.ws = new WebSocket(`${wsUrl}/api/v1/agents/${agentName}/ws`);
20
31
  this.ws.onmessage = (event) => {
21
32
  const data = JSON.parse(event.data);
@@ -25,6 +36,10 @@ export class AgentEventStream {
25
36
  timestamp: data.timestamp || "",
26
37
  payload: data.payload || {},
27
38
  };
39
+ const key = this.dedupKey(agentEvent);
40
+ if (this.seen.has(key))
41
+ return;
42
+ this.seen.add(key);
28
43
  if (this.resolve) {
29
44
  const r = this.resolve;
30
45
  this.resolve = null;
@@ -51,6 +66,10 @@ export class AgentEventStream {
51
66
  }
52
67
  };
53
68
  }
69
+ dedupKey(e) {
70
+ const normType = e.type === "task_started" ? "user_message" : e.type;
71
+ return `${e.timestamp}:${normType}`;
72
+ }
54
73
  [Symbol.asyncIterator]() {
55
74
  return {
56
75
  next: () => {
package/dist/watch.d.ts CHANGED
@@ -9,6 +9,8 @@ export interface AgentEvent {
9
9
  }
10
10
  /**
11
11
  * Async iterable stream of agent events over WebSocket.
12
+ * Yields pre-fetched history events first, then live WebSocket events,
13
+ * deduplicating by timestamp+type.
12
14
  *
13
15
  * @example
14
16
  * for await (const event of client.watchAgent("my-agent")) {
@@ -22,7 +24,9 @@ export declare class AgentEventStream implements AsyncIterable<AgentEvent> {
22
24
  private queue;
23
25
  private resolve;
24
26
  private done;
25
- constructor(wsUrl: string, agentName: string);
27
+ private seen;
28
+ constructor(wsUrl: string, agentName: string, historyEvents?: AgentEvent[]);
29
+ private dedupKey;
26
30
  [Symbol.asyncIterator](): AsyncIterator<AgentEvent>;
27
31
  close(): void;
28
32
  }
package/dist/watch.js CHANGED
@@ -6,6 +6,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.AgentEventStream = void 0;
7
7
  /**
8
8
  * Async iterable stream of agent events over WebSocket.
9
+ * Yields pre-fetched history events first, then live WebSocket events,
10
+ * deduplicating by timestamp+type.
9
11
  *
10
12
  * @example
11
13
  * for await (const event of client.watchAgent("my-agent")) {
@@ -14,11 +16,20 @@ exports.AgentEventStream = void 0;
14
16
  * }
15
17
  */
16
18
  class AgentEventStream {
17
- constructor(wsUrl, agentName) {
19
+ constructor(wsUrl, agentName, historyEvents) {
18
20
  this.queue = [];
19
21
  this.resolve = null;
20
22
  this.done = false;
23
+ this.seen = new Set();
21
24
  this.agentName = agentName;
25
+ // Seed dedup set and queue with history events.
26
+ if (historyEvents) {
27
+ for (const e of historyEvents) {
28
+ const key = this.dedupKey(e);
29
+ this.seen.add(key);
30
+ this.queue.push(e);
31
+ }
32
+ }
22
33
  this.ws = new WebSocket(`${wsUrl}/api/v1/agents/${agentName}/ws`);
23
34
  this.ws.onmessage = (event) => {
24
35
  const data = JSON.parse(event.data);
@@ -28,6 +39,10 @@ class AgentEventStream {
28
39
  timestamp: data.timestamp || "",
29
40
  payload: data.payload || {},
30
41
  };
42
+ const key = this.dedupKey(agentEvent);
43
+ if (this.seen.has(key))
44
+ return;
45
+ this.seen.add(key);
31
46
  if (this.resolve) {
32
47
  const r = this.resolve;
33
48
  this.resolve = null;
@@ -54,6 +69,10 @@ class AgentEventStream {
54
69
  }
55
70
  };
56
71
  }
72
+ dedupKey(e) {
73
+ const normType = e.type === "task_started" ? "user_message" : e.type;
74
+ return `${e.timestamp}:${normType}`;
75
+ }
57
76
  [Symbol.asyncIterator]() {
58
77
  return {
59
78
  next: () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@komputer-ai/sdk",
3
- "version": "0.11.2",
3
+ "version": "0.11.3",
4
4
  "description": "TypeScript SDK for the komputer.ai platform",
5
5
  "author": "kontroloop-ai",
6
6
  "license": "MIT",
@@ -17,10 +17,14 @@
17
17
  "module": "./dist/esm/index.js",
18
18
  "sideEffects": false,
19
19
  "scripts": {
20
- "build": "tsc && tsc -p tsconfig.esm.json"
20
+ "build": "tsc && tsc -p tsconfig.esm.json",
21
+ "test": "vitest run src/client.test.ts",
22
+ "test:integration": "vitest run src/integration.test.ts"
21
23
  },
22
24
  "devDependencies": {
25
+ "@types/ws": "^8.18.1",
23
26
  "typescript": "^4.0 || ^5.0",
24
- "vitest": "^4.1.4"
27
+ "vitest": "^4.1.4",
28
+ "ws": "^8.20.0"
25
29
  }
26
30
  }