@forwardimpact/svcagent 0.1.111 → 0.1.114

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/package.json CHANGED
@@ -1,16 +1,17 @@
1
1
  {
2
2
  "name": "@forwardimpact/svcagent",
3
- "version": "0.1.111",
3
+ "version": "0.1.114",
4
4
  "description": "Core orchestration service for Guide",
5
5
  "license": "Apache-2.0",
6
6
  "author": "D. Olsson <hi@senzilla.io>",
7
7
  "type": "module",
8
8
  "main": "index.js",
9
9
  "engines": {
10
- "bun": ">=1.2.0"
10
+ "bun": ">=1.2.0",
11
+ "node": ">=18.0.0"
11
12
  },
12
13
  "scripts": {
13
- "dev": "bun --watch server.js",
14
+ "dev": "node --watch server.js",
14
15
  "start": "bunx download && bun server.js",
15
16
  "test": "bun run node --test test/*.test.js"
16
17
  },
@@ -22,5 +23,11 @@
22
23
  },
23
24
  "devDependencies": {
24
25
  "@forwardimpact/libharness": "^0.1.5"
26
+ },
27
+ "files": [
28
+ "proto/"
29
+ ],
30
+ "publishConfig": {
31
+ "access": "public"
25
32
  }
26
33
  }
@@ -0,0 +1,48 @@
1
+ syntax = "proto3";
2
+
3
+ package agent;
4
+
5
+ import "common.proto";
6
+ import "tool.proto";
7
+
8
+ service Agent {
9
+ rpc ProcessStream(AgentRequest) returns (stream AgentResponse);
10
+ rpc ProcessUnary(AgentRequest) returns (AgentResponse);
11
+ rpc ListSubAgents(common.Empty) returns (tool.ToolCallResult);
12
+ rpc RunSubAgent(RunSubAgentRequest) returns (tool.ToolCallResult);
13
+ rpc ListHandoffs(ListHandoffsRequest) returns (tool.ToolCallResult);
14
+ rpc RunHandoff(RunHandoffRequest) returns (tool.ToolCallResult);
15
+ }
16
+
17
+ message AgentRequest {
18
+ repeated common.Message messages = 1;
19
+ optional string resource_id = 2;
20
+ optional string llm_token = 3;
21
+ optional string agent = 4;
22
+ }
23
+
24
+ message AgentResponse {
25
+ string object = 1;
26
+ int64 created = 2;
27
+ string model = 3;
28
+ common.Usage usage = 5;
29
+ string resource_id = 6;
30
+ repeated common.Message messages = 7;
31
+ }
32
+
33
+ message RunSubAgentRequest {
34
+ string resource_id = 1;
35
+ string agent_id = 2;
36
+ string prompt = 3;
37
+ optional string llm_token = 4;
38
+ }
39
+
40
+ message ListHandoffsRequest {
41
+ string resource_id = 1;
42
+ bool void = 2; // Ensures non-empty schema for OpenAI function calling
43
+ }
44
+
45
+ message RunHandoffRequest {
46
+ string resource_id = 1;
47
+ string label = 2;
48
+ }
package/server.js DELETED
@@ -1,48 +0,0 @@
1
- import { Server, createClient } from "@forwardimpact/librpc";
2
- import { createServiceConfig } from "@forwardimpact/libconfig";
3
- import { createResourceIndex } from "@forwardimpact/libresource";
4
- import { AgentMind, AgentHands } from "@forwardimpact/libagent";
5
- import { createTracer } from "@forwardimpact/librpc";
6
- import { createLogger } from "@forwardimpact/libtelemetry";
7
-
8
- import { AgentService } from "./index.js";
9
-
10
- const agentConfig = await createServiceConfig("agent");
11
-
12
- // Initialize observability
13
- const logger = createLogger("agent");
14
- const tracer = await createTracer("agent");
15
-
16
- const memoryClient = await createClient("memory", logger, tracer);
17
- const llmClient = await createClient("llm", logger, tracer);
18
- const toolClient = await createClient("tool", logger, tracer);
19
-
20
- const resourceIndex = createResourceIndex("resources");
21
-
22
- // Create callbacks for AgentHands and AgentMind
23
- const callbacks = {
24
- memory: {
25
- append: memoryClient.AppendMemory.bind(memoryClient),
26
- get: memoryClient.GetWindow.bind(memoryClient),
27
- },
28
- llm: {
29
- createCompletions: llmClient.CreateCompletions.bind(llmClient),
30
- },
31
- tool: {
32
- call: toolClient.CallTool.bind(toolClient),
33
- },
34
- };
35
-
36
- const agentHands = new AgentHands(callbacks, resourceIndex);
37
- const agentMind = new AgentMind(
38
- agentConfig,
39
- callbacks,
40
- resourceIndex,
41
- agentHands,
42
- );
43
-
44
- const service = new AgentService(agentConfig, agentMind, resourceIndex);
45
-
46
- const server = new Server(service, agentConfig, logger, tracer);
47
-
48
- await server.start();
@@ -1,137 +0,0 @@
1
- import { test, describe, beforeEach } from "node:test";
2
- import assert from "node:assert";
3
-
4
- // Module under test
5
- import { AgentService } from "../index.js";
6
- import {
7
- createMockServiceConfig,
8
- createSilentLogger,
9
- createMockResourceIndex,
10
- } from "@forwardimpact/libharness";
11
-
12
- describe("agent service", () => {
13
- describe("AgentService", () => {
14
- test("exports AgentService class", () => {
15
- assert.strictEqual(typeof AgentService, "function");
16
- assert.ok(AgentService.prototype);
17
- });
18
-
19
- test("AgentService has ProcessStream method", () => {
20
- assert.strictEqual(
21
- typeof AgentService.prototype.ProcessStream,
22
- "function",
23
- );
24
- });
25
-
26
- test("AgentService has ProcessUnary method", () => {
27
- assert.strictEqual(
28
- typeof AgentService.prototype.ProcessUnary,
29
- "function",
30
- );
31
- });
32
-
33
- test("AgentService constructor accepts expected parameters", () => {
34
- // Test constructor signature by checking parameter count
35
- assert.strictEqual(AgentService.length, 3); // config, agentMind, resourceIndex
36
- });
37
-
38
- test("AgentService has proper method signatures", () => {
39
- const methods = Object.getOwnPropertyNames(AgentService.prototype);
40
- assert(methods.includes("ProcessStream"));
41
- assert(methods.includes("ProcessUnary"));
42
- assert(methods.includes("constructor"));
43
- });
44
- });
45
-
46
- describe("AgentService business logic", () => {
47
- let mockConfig;
48
- let mockAgentMind;
49
- let mockResourceIndex;
50
- let _mockLogger;
51
-
52
- beforeEach(() => {
53
- mockConfig = createMockServiceConfig("agent", {
54
- assistant: "common.Assistant.test-assistant",
55
- });
56
-
57
- mockAgentMind = {
58
- process: async () => ({
59
- resource_id: "test-conversation",
60
- choices: [
61
- { message: { role: "assistant", content: "Test response" } },
62
- ],
63
- }),
64
- };
65
-
66
- mockResourceIndex = createMockResourceIndex();
67
-
68
- _mockLogger = createSilentLogger();
69
- });
70
-
71
- test("constructor validates required dependencies", () => {
72
- assert.throws(
73
- () => new AgentService(mockConfig, null, mockResourceIndex),
74
- /agentMind is required/,
75
- );
76
- assert.throws(
77
- () => new AgentService(mockConfig, mockAgentMind, null),
78
- /resourceIndex is required/,
79
- );
80
- });
81
-
82
- test("ProcessStream throws error for missing user message", async () => {
83
- const mockAgentMindWithError = {
84
- process: async () => {
85
- throw new Error("No user message found in request");
86
- },
87
- };
88
-
89
- const service = new AgentService(
90
- mockConfig,
91
- mockAgentMindWithError,
92
- mockResourceIndex,
93
- );
94
-
95
- const mockCall = {
96
- request: { messages: [], llm_token: "test-token" },
97
- write: () => {},
98
- end: () => {},
99
- };
100
-
101
- await assert.rejects(
102
- () => service.ProcessStream(mockCall),
103
- /No user message found in request/,
104
- );
105
- });
106
-
107
- test("creates service instance with all dependencies", () => {
108
- const service = new AgentService(
109
- mockConfig,
110
- mockAgentMind,
111
- mockResourceIndex,
112
- );
113
-
114
- assert.ok(service);
115
- assert.strictEqual(service.config, mockConfig);
116
- });
117
-
118
- test("ProcessStream calls agentMind and returns response", async () => {
119
- const service = new AgentService(
120
- mockConfig,
121
- mockAgentMind,
122
- mockResourceIndex,
123
- );
124
-
125
- const mockCall = {
126
- request: {
127
- messages: [{ role: "user", content: "Hello" }],
128
- llm_token: "test-token",
129
- },
130
- write: () => {},
131
- end: () => {},
132
- };
133
-
134
- await service.ProcessStream(mockCall);
135
- });
136
- });
137
- });